4

In the React tutorial , It says

React elements are immutable. Once you create an element, you can’t change its children or attributes. An element is like a single frame in a movie: it represents the UI at a certain point in time. With our knowledge so far, the only way to update the UI is to create a new element and pass it to ReactDOM.render().

In the Next Heading, It says

React only updates What's necessary

React DOM compares the element and its children to the previous one, and only applies the DOM updates necessary to bring the DOM to the desired state.

Example took by them -

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(element, document.getElementById('root'));
}

setInterval(tick, 1000);

In this example React Only updates the time - <h2>It is {new Date().toLocaleTimeString()}.</h2> line of the code. Because this is only necessary changes but I couldn't be able to understand how React changing the Immutable object as they have mentioned

React elements are immutable. Once you create an element, you can’t change its children or attributes.

So rather than only changing the "Just Time Part" (of above code example), It should change whole React Element. I couldn't be able to understand how could React does necessary updates inside the Immutable object (in above case it is the element) or I'm missing something?

Abhijith Konnayil
  • 4,067
  • 6
  • 23
  • 49
Joshi Yogesh
  • 142
  • 1
  • 12
  • 2
    The element is indeed immutable. React isn't changing it, it's throwing the whole thing away and making a completely new version. (`element` is only in scope inside the `tick` function, as soon as it has run, each second, `element` will be garbage-collected). Of course this is very inefficient, so if you read on in the docs, you will see it goes on to React "components", which are mutable, and automatically selectively updated themselves in response to certain triggers. As far as I know, "real world" React applications only ever use Components, not "elements". – Robin Zigmond Sep 22 '18 at 19:42
  • 1
    I'd recommend reading : https://reactjs.org/docs/state-and-lifecycle.html – Mathieu K. Sep 22 '18 at 19:58
  • @RobinZigmond What does it mean by "completely new version" ? Does new version means only the line which includes time (

    It is {new Date().toLocaleTimeString()}). Yes , I think that's true - 'element' will be garbage -collected. No I haven't gone through component, I'll read.

    – Joshi Yogesh Sep 22 '18 at 20:04
  • @JoshiYogesh - I'm actually confused myself now, lol. (Wasn't that long ago that I taught myself React, I'm hardly an expert or anything.) I actually meant that the whole element is "thrown away" (garbage-collected", and a new one made - and I'm still pretty sure this is correct as far as `element`, the JS object, is concerned. But after more thought (including reading the answer below) I do think that React will only change the smallest necessary part when updating the DOM itself. That doesn't change the fact that elements are immutable from a JS point of view. – Robin Zigmond Sep 22 '18 at 20:34

2 Answers2

4

It doesn't do updates on React Element Tree ('the immutable object'). It compares previous tree with the current one and does necessary updates to the DOM.

React Element Tree is a simplified form of the DOM. It's like a snapshot. React has the current snapshot and when the state of an application changes, it creates a new state that reflects how the DOM should look like. React compares those two snapshots and makes required changes to the DOM so that it mirrors the new snapshot. After that the old, outdated snapshot is trashed and the new one becomes the current snapshot of the DOM.

Basically, you have:

  • the state of an app
  • description how an app should look like for a given state (the React code you write)
  • snapshot (React Element Tree)
  • Diffing and updating machinery (React library)
  • DOM

DOM or external world (i.e. server) produce events that change the state. A new snapshot is created for that state based on the description. Old and new snapshots are compared and changes are introduced to the DOM. This process repeats over and over again.

You can see and learn more about React elements in this fantastic blog post: https://reactjs.org/blog/2015/12/18/react-components-elements-and-instances.html

marzelin
  • 10,790
  • 2
  • 30
  • 49
1

React components are built with createElement internally:

React.createElement(type, props)

And thus, when any changes applied on its props the value gets updated but not its type.

For example:

React.createElement('h1', 'Hello, world!')
// first param is type, and second is prop

Here the prop is not changed, and thus this element will not be updated.


The component could be written with createElement like:

React.createElement('div',
   React.createElement('h1', 'Hello world!'),
   React.createElement(....),
   React.createElement(...)
)

So, whenever any of the props of the particular element gets changes, that element will only be updated.

Why only props are updated, but not type ie. element?

It's because React store them in ReactDOM object but not HTML DOM. And it carefully analyse what it needs to be updated. ReactDOM is simply an object with key:value pair.

For example, React initialize it's dom like:

var ReactDOM = {}

Now, whatever the property need update, can be handled on that.

Object.defineProperties(ReactDOM, {
  type: { // creating immutable property
    value: 'h1',
    writable: false,
    configurable: false
  },
  props: {
    writable: true,
    value: 'MY PROPS'
  }
});
Object.seal(ReactDOM)

Now, the props can be changed but not type.

ReactDOM.props = 'will be updated'
ReactDOM.type = 'will not be updated'
console.log(ReactDOM.type) // 'h1'
console.log(ReactDOM.props) // 'will be updated'

I hope this makes clear up things that React's elements are immutable.

Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231