For instance React's componentWillMount():
This is the only lifecycle hook called on server rendering. Generally, we recommend using the constructor() instead.
And in React's componentDidMount()
componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here.
However I do not see anything in the Angular doc specifying which ones are executed on the server and which ones are executed on the browser (or both). Or should I assume that all of them are executed on both? If so, how do you do things that require the DOM (window, document, etc.)?
No, it doesn't. It runs the same hooks.
There's plenty of devices you can use to avoid contact with plain DOM, like HostBinding and HostListener decorators, Renderer and ElementRef classes. Remember that Angular 2 is a high-abstraction tool. It doesn't promotes access the DOM, although it is possible. Also, for server-side rendering, DI also comes to the rescue when there are different implementations for server and client.
Learn about Angular Universal to know more about server-side rendering at https://github.com/angular/universal.
If that doesn't answer your question, please place a more specific question.
Related
As you know, for the sake of good performance, we always try to minimize rendering in single page applications. For instance, in React whenever a state or props change inside a component, that change make that component re execute, re evaluate and finally re render.
So, are there any similar conditions in Angular ? and what are the best practices and patterns for reducing extra rendering ?
This is a huge topic to cover here but I would suggest the following article for starters: https://blog.angular-university.io/how-does-angular-2-change-detection-really-work/
TLDR;
What happens is that Angular at startup time will patch several low-level browser APIs, such as for example addEventListener, which is the browser function used to register all browser events, including click handlers. Angular will replace addEventListener with a new version
So by extending base functionality, angular understands changes that trigger re-evaluation of values and rerendering needs.
As an extra, we need to mention that the comparisons are not deep inside reference types, so some handling should happen.
In the article, several methods for performance tweaking are mentioned like
On push change detection method.
Disabling automatic detection for a component and triggering the cycles manually.
Using immutable objects with the help of libraries line immutable.js
As you can understand, these being their own pitfalls and considerations
I would like to know if it's fully consistent with the React principles.I made a React App without state and props.I've put pure javascript only inside componentDidMount e.g.
componentDidMount(){
const first = document.getElementById('first');
const second = document.getElementById('second');
function funk(){
console.log(first.innerHTML);
second.innerHTML = "Arrr";
}
funk();
}
Of course it's just an example, my app is far more complex.
Technically speaking, You can (as you may already know).
Should you do it? A big and glowing NO!.
With this approach of targeting the DOM directly, you are bypassing and missing most of the goodness that react has to offer with the Reconciliation and The Diffing Algorithm.
If you really (really) need to target the DOM, you can use react's ref API.
And you can see in their docs it's should be used sparingly :
Don’t Overuse Refs
Your first inclination may be to use refs to “make
things happen” in your app. If this is the case, take a moment and
think more critically about where state should be owned in the
component hierarchy. Often, it becomes clear that the proper place to
“own” that state is at a higher level in the hierarchy. See the
Lifting State Up guide for examples of this.
Yes and no
Yes, you can use it in some cases for utilizing complex jQuery plugins integrating react as a part of your project and so on...
I know that there are lots of haters of such approach but we should also understand business if it's possible to achieve a goal without spending 40-80hrs for coding it yourself - go for it.
No, you should not do any DOM manipulation in component live cycle methods unless you are very good with react and completely understand how things work internally in this library.
Changing DOM in such way will most likely cause performance issues because your components will not be able to utilize shadow DOM, as a result, your components will perform DOM manipulation after every change and could potentially slow down the application.
What is happening inside here from what I understand is that you're building out your own render method, which will render the html of the h1. This render method is called by React.DOM to figure out what to give to the virtual dom. The same goes for methods such as componentDidMount right? If you put in any of those lifecycle methods or render, React will call them accordingly to fit inside their code, but if create other functions, those will just be helper functions for you to render stuff with, right?
I guess I'm just trying to understand which part of the Component class is being used by React.DOM and which parts am I building. It seems weird that some methods are used to "configure" the component while others are used as helpers. What code inside the Component class is the React.DOM using? Is it like stuff to figure out the diffs on when to rerender stuff?
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Here's something to consider: ages ago in times long past, React and React-DOM were one in the same. React was targeted solely to webapps. So we could use h1, div, span, img, all of that using React only.
Now let me ask you this question. Let's say they wanted to take React, and make it so it could not only render to the DOM of a webpage, but also render the different components of a native mobile application? What would you do in that situation?
Obviously, all of those aforementioned HTML DOM elements, h1s etc etc, would be utterly useless! Android and iOS interiors do not know what any of those are whatsoever.
So the logical solution is to abstract that away. Instead of having those DOM nodes be an inherent part of React, instead make it so that React can render wherever and whatever!
You see, the React engine works pretty much the same in both React Native (mobile development), and standard web-based React with React-DOM. The lifecycle methods, the principles of design, the reconciliation, the entire engine is the same. Because React isn't about HTML or native applications, it's about a paradigm of data flow from application state into UI state.
So then, what is React-DOM doing with your component? Not a whole lot of anything, really. All of the diffing, data flow, etc etc are all handled by React.
What React-DOM does is it knows how to render the data provided by a React element as a DOM node. It knows how to update them, how to delete, them, all of that. You see, having all those abilities as part of the React core would not be ideal now, because React targets other platforms where those abilities are useless. And they would only bloat the package.
The only method inside the class you 'have' to provide is the render. The other component lifecycle methods, as you mentioned, are called if provided when those lifecycle methods come into play. If you have no need to tap into those other lifecycle methods (component just returns some markup based on props provided to it) and your component doesn't need its own state then I would highly recommend just using stateless functional components. The docs provided by React team are good for explaining this -
https://facebook.github.io/react/docs/components-and-props.html
As far as the 'helper methods' you mentioned, yes you can define as many methods as you need in your class. It is very common to split up some of the more complex rendering logic into smaller easier to read functions for code readability.
I saw this line as an answer to another question on here:
"componentWillMount should be componentDidMount, or else you'll leak event emitters in node."
and I don't really understand it. Can someone explain with more detail?
More info:
Building a react application with flux, as part of the initial render, a child component computes some data. Ideally, after this data is computed, I would like to call an action that updates the store's state with a portion of this new data.
Normally, updating the store's state emits a change event that causes a re-render. However, because the change listener isn't being added until componentDidMount (rather than in componentWillMount), my top level component isn't able to listen for the change that occurs during the initial render and initiate a re-render.
If I move the addChangeListener to componentWillMount that would seem to fix this issue, but the above quote suggests that this is a bad idea?
I think the prevailing wisdom that listeners should be set in componentDidMount because it prevents problems in isomorphic applications is a mistake. I think in 98% of cases for non-isomorphic applications setting listeners in either componentWillMount and componentDidMount will work the same way, but it is conceptually wrong and in the 2% of cases (such as the example given in the original question) it will do the wrong thing.
There are git issue discussions and comments in the React source code suggesting that it would be preferred that componentWillMount wasn't called on the server at all, but if it isn't then problems are created in the checksum test comparing the server prerender to the client initial render. Having componentWillMount on the server means that it isn't executed as part of the component lifecycle in this case, but this is being used as an excuse to not count it as part of the lifecycle in any case.
In fact, componentWillMount is exactly the right place to register listeners if you are not creating an isomorphic application. If you are creating an isomorphic application then you have to make some compromises due to the checksum/lifecycle issue not being ideal in this case (maybe just testing for the server environment and then not registering listeners?).
In non-isomorphic applications adding listeners in componentWillMount can save unnecessary re-renders in some cases and will register them in document order. The advantage of document order is that if you have a way to flush pending events as components are re-rendered (for example, takeRecords on a MutationObserver) then you can ensure the document is re-rendered top down instead of bottom up, converting the rendering complexity to linear from polynomial.
Additionally, there is no danger period between the initial render and when the listener is registered where the Store can change without triggering a render, causing the view to be out of sync with the Store (the example problem given in the original question). If the listener is registered in componentDidMount you either need to make sure the Store isn't changed in componentDidMount calls in children, or else force a re-render/re-sync after registering the listener, which if done in componentDidMount is done in reverse document order which may be polynomial complexity (depending on how/if the React setStates are aggregated).
Is hard to understand what that quote means without more context. What I can tell you is that there are huge differences between the two of those methods.
On one hand, componentWillMount is called before the component is actually added to the DOM. This is the last chance you have to update component's state and get it rendered before the component is rendered by the browser.
On the other hand, componentDidMount is called once the component has been attached to the DOM (the real one).
What you need really depends on your use case. In general, componentDidMount is used to integrate with other libraries (like jQuery), it provides a way to modify the HTML rendered by the component.
I suggest you to read these links:
https://facebook.github.io/react/docs/component-specs.html#mounting-componentwillmount
https://facebook.github.io/react/docs/component-specs.html#mounting-componentdidmount
https://facebook.github.io/react/tips/use-react-with-other-libraries.html
So I am looking to write integration level tests (where you are talking to a real database and really nothing is mocked) for a ReactJS application and figured Selenium is the default choice for this type of testing. With Angular 1.x, you can tell if angular's digest cycle is still process the DOM which removes the need to add in sleeps which are inefficient and flakey.
Is there something similar in ReactJS that I can use instead of a bunch of flakey sleep commands?
Always rendering from a root component
There's a callback that you can pass to the render function:
ReactComponent render(
ReactElement element,
DOMElement container,
[function callback]
)
You can also listen to the componentDidUpdate method of that top component.
Unfortunately this will only work if you always render from the top component, which somehow means you manage all the state outside of React, without using any local state, and use it in a purely functional way as an efficient templating engine. Some frameworks help you do so.
Even Flux does not really enforce this (at least the original implementation) because Flux stores are not necessarily injected as props from the very top. (They are in atom-react)
Not always rendering from a root component
I don't know there is any elegant solution to this problem but here's what I would do:
Implement all lifecycle methods on all your components, for example with a Mixin, and call a global function notifyReactIsWorking from these callbacks
Debounce the notifyReactIsWorking with _.debounce(changeMeter, 1000, false)
This way, when notifyReactIsWorking gets called, this somehow means that React has stabilized because not a single lifecycle method has been called for more than 1 second.
This is a hack but probably should work in most cases.
Also interested in more efficient solutions :)