How does React remove asynchronous behavior? - javascript

I have been reading this, and I came across a line in the Redux documentation
Libraries like React attempt to solve this problem in the view layer
by removing both asynchrony and direct DOM manipulation.
I understood the part where React does not allow DOM manipulations as it abstracts the actual rendering using the render() method. I am confused with the second part.
How does React remove the asynchrony? Can someone please explain with examples or valid use cases.

It removes asynchronous behavior from the view layer by design. You must not do async stuff in render or what is rendered will be broken.
Libraries like React attempt to solve this problem in the view layer
by removing both asynchrony and direct DOM manipulation [from the render method].
You are missing the last sentence which gives further explanations:
However, managing the state of your data is left up to you.
This is where Redux enters.
To wrap up, there must be no async calls in render method but there can be some async stuff happening in the state management part handled by Redux. You can't do async stuff in the render method by design. If you you do so it won't work.

I think that good example would be an rendering library like dust.js
It renders template asynchronous, creates document fragment, and let user handle appending in callback.
And well... I think that any DOM mutations performed in callbacks counts into this case.

Related

Why React doesn't use promise.resolve for batching updates?

Currently, React only batches updates in functions that are called by the React itself. like event handlers and lifecycles. And as far as I know, React simply calls these functions like they are wrapped in unstable_batchedUpdates.
Lets assume it's something like the following:
unstable_batchedUpdates(() => {
instance.componentDidMount();
});
So right now, we have to manually wrap functions that are called by someone other than the React inside of the unstable_batchedUpdates.
I'm also aware that in the concurrent mode, we have the updates train concept and we batch all of the state updates together.
But I have two questions,
First, how does this update train works? What mechanism decides which updates should be on the train? Is it only the time of occurrence?
And second, Why it has to be this complicated? why we couldn't do something similar to what Vue does and wrap all of the setState calls inside of a nextTick function? I know it's almost similar to what we will have in the concurrent mode, but what kind of bottlenecks and problems do we have for adding it right now, without the concurrent mode enabled?
I'm thinking of starvation problem. But I'm not sure.
Thanks in advance.

Where is the code that causes setState (React) to be asynchronous?

I recently read through a large portion of the React and ReactDOM codebase in order to get an understanding of what happens when a call to setState occurs. At this point, I would say that I understand the sequence of events at a high level. A call to setState results in a message being added to a queue of updates that need to be processed. The updates are processed and changes to the DOM are only made if necessary.
Here's where I am lost. There are hundreds of blog posts discussing the asynchronous behavior of setState. While I don't doubt that setState is asynchronous, I cannot find a line of code in the ReactDOM codebase that would introduce asynchronous behavior. Does anyone know exactly where this happens?
First of all setState may be execute in async way, but it is not allwys executed as such. Ben Nadel list some of his findings in setState() State Mutation Operation May Be Synchronous In ReactJS
To summarize setStates seems to gets batched in situations where react can intercept originating event, like onClick handlers. Since react creates actual DOM from virtual react DOM (and since it is aware of semantics of attributes) it can wrap any of onClick handlers that you provide into something like this
wrappedHandler = () => {
turnBatchingOn()
originalHanlder()
executeBatched()
}
In this case you get async behavior, all setState calls get enqueued, and they get executed only after your original onClick handler has finished executing.
Note this is not actual react code it is just my speculation how it is async effect achieved. I understand it is not actual line of code that does it, but I think it could help you find it.
Best article explaining setState implementation that I found is on React Kung Fu
i think setState isn't async, but there is an optimization of multiple setState calls and in some cases sync canot be guaranteed.

Server rendering with react-router v4 and prefetching data

I worked a lot with server side rendering with RR 3 so I wanted to see how it works in the context of v4. I followed the tutorial from the website, but because the rendering is happening now together with the route match, there's no way to implement prefetching data as before.
Here's how I used to do server rendering with v3:
https://github.com/alexnm/react-seed/blob/master/server/index.js
Based on the match function, I would call all the prefetch functions from all the component tree and then wait with a Promise.all for them to finish, then trigger the renderToString function and return the html.
In RR4, we have only the <ServerRouter> component, so the current solution I came with is duplicating the render code:
https://github.com/FortechRomania/react-redux-complete-example/blob/master/src/server/index.js
I'm also using the render function on the <Match> tag to trigger the prefetch actions. It's ugly and introduces all sorts of dependencies in the parent component of the page I want to render with prefetched data.
What am I missing here? Has anyone found a better solution for this scenario? I haven't found anything useful yet.
The new RR4 documentation has a working example: https://reacttraining.com/react-router/web/guides/server-rendering/data-loading

onrender vs init in Ractive.js

I recently started trying out Ractive.js. I was particularly interested in its components. One of the things I noticed immediately is that many of the examples are using the init option. However when I try to use the init in my code I get a deprecation notice and it then recommends using onrender instead. onrender however had far fewer examples than init and some of the functions such as this.find weren't available inside onrender. I looked through the Github issues but couldn't find any reasoning behind this change or what the suggested path forward for selecting elements specific to a component was.
I created a test pen to try creating a recursive component with the new API but I had to resort to using jQuery and an undocumented fragment api to select specific DOM nodes I needed to manipulate. I feel this is against how Ractive expects you to do things, but I couldn't figure out what was expected of me with the existing documentation.
What's the major differences between the init and onrender options and how does onrender expect you to handle manipulating specific elements and their events within a component?
You can use this.find() inside onrender (if you can't for some reason, you've found a bug!).
We split init into oninit and onrender a while back for a number of reasons. Those examples you mention are out of date - are they somewhere on ractivejs.org? If so we should fix them. You can find more information about lifecycle events here on the docs, but the basic difference is this:
init was called on initial render (assuming the component was rendered, i.e. never in node.js, if you were doing server-side rendering)
oninit is called on creation, immediately before rendering. It is called once and only once for any Ractive instance, whether or not it gets rendered. It's therefore a good place to set up event handlers etc. The opposite of oninit is onteardown, so you can use that handler to do any cleanup if necessary (or use this.on('teardown'...) inside oninit).
onrender is called whenever a component is rendered. This could happen more than once (if you unrendered, then re-rendered, etc) or not at all. If you need to store DOM references etc, this is the place. The opposite of onrender is onunrender.
I did a fork of your codepen, replacing the jQuery stuff with more idiomatic Ractive code to show how you'd do it without storing DOM references.

Why does React require jsdom for testing?

When writing tests for React components, you have to render them into the DOM in order to make assertions about their correctness. For example, if you want to test that a certain class is added to a node given a certain state, you have to render into a DOM node, then inspect that DOM node via the normal DOM API.
The thing is, considering React maintains a virtual DOM into which it renders, why can't we just assert on the virtual DOM once the component is rendered? That seems to me like a very good reason to have something like the virtual DOM.
Have I missed something?
You haven't really missed anything. We're working on making this better. The virtual parts have always been very much an implementation detail of React, not exposed in any useful or reliable way for testing. We have some methods in our test helpers which wrap up the internal lookups which sometimes avoids looking at the actual DOM but we need more.

Categories

Resources