Reconciliation has bug that is occured when client starts hydration

cheolheon
创建于
2018-04-28 17:02:34

Do you want to request a feature or report a bug?
bug

What is the current behavior?

// Static.js
import React from 'react'

function Static() {
  return (
    <div className="i am static" style={{ backgroundColor: 'red', width: '100%', height: '300px' }}>
      Static
    </div>
  )
}

export default Static
// Dynamic.js
import React from 'react'

function Dynamic() {
  return (
    <div className="i am dynamic" style={{ backgroundColor: 'blue', width: '100%', height: '300px' }}>
      Dynamic
    </div>
  )
}

export default Dynamic
// App.js
import React from 'react'
import Static from './Static'
import Dynamic from './Dynamic'

class App extends React.Component {
  constructor(props) {
    super(props)
    
    this.mounted = false
    this.state = {
      loaded: !isBrowser
    }

    if (isBrowser) {
      new Promise((resolve) => {
        setTimeout(() => {
          const nextState = {
            loaded: true
          }
          if (this.mounted) {
            this.setState(nextState)
          } else {
            this.state = nextState
          }
        }, 200)
      })
    }
  }

  componentDidMount() {
    this.mounted = true
  }

  render() {
    return (
      <div>
        {this.state.loaded ? <Dynamic /> : null}
        <Static />
      </div>
    )
  }
}

export default App

First, Server sends React App without any asynchronous component loading.

Second, Client starts hydration with loading <Dynamic /> component asynchronously.
(In our real production, We used code splitting with webpack and loaded it with import(). In this example, I just controlled loaded state for making app simple.)
During <Dynamic /> is being loaded, App renders null instead.

Finally, Let's see the result.

screen shot 2018-04-29 at 1 43 47 am

Why background-color of <Static /> component is changed to blue?

screen shot 2018-04-29 at 1 47 50 am

<Dynamic /> took <Static /> for dinner.

AFAIK, React don't touch the result of client rendering if it is different with server html.
When I moved to another page through client-side routes I cannot find this situation.

So, I guess it occurs only when client hydrates the result of server-side rendering .

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:

You can check it easily with https://github.com/cheolheon/react-16-reconciliation-bug
Clone it, run yarn, yarn start, and open http://localhost:3000.

What is the expected behavior?
screen shot 2018-04-29 at 1 44 08 am

screen shot 2018-04-29 at 1 57 42 am

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

React 16.3.2
Browser: Chrome (Safari too.)
OS: MacOS (Windows or Linux too.)

React 15 works well without any bug.
Check it at https://github.com/cheolheon/react-16-reconciliation-bug/tree/react-15/src
(react-15 branch)

5条回答
gaearon
回复于
2018-04-28 17:09:51
#1

Does this help?

#10591

cheolheon
回复于
2018-04-28 17:21:13
#2

@gaearon
Okay it helps me partly, but I have one question.

Do you want to say this problem is intended, and it is to be expected?
Otherwise do you just hold it on for performance, user experience, or any other issues?

In my case, It's just not to make client different with server.
I want to make same between client and server but there is a space at client for performance issue.
server (#1) -> client (#2, in a short time for loading chunk asynchronously) -> client (#1)

In generic case, server and client are same.
server (#1) -> client (#1)

In #10591 case, server and client are different. That's all.
server (#1) -> client (#2)

Is there any methods to implement it?

meggamind
回复于
2018-07-04 00:33:59
#3

@gaearon Can you assign this to me? or should I just investigate and submit PR?

gaearon
回复于
2018-08-02 19:23:19
#4

I want to make same between client and server but there is a space at client for performance issue.

We don't have a good solution for temporary mismatches, sorry. We probably will in the future.

cheolheon
回复于
2018-08-16 07:33:23
#5

@gaearon
It's okay. I solved it with rendering root element of child component(ex, div, p, ...) instead of null during component is loading it asynchronously.

当前位于第1页,总计5 条回复

推荐相似问题

encoded character in table td tags showing as string incorrectly

Encoded characters for example &pound;, &#36; can not show as £, $ if adding it into <td>. These characters are fine if
讨论数 4
react
创建时间:2018-04-28 14:45:37

setState callback fired with wrong state context when using ReactDOM.unstable_deferredUpdate

Do you want to request a feature or report a bug? bug What is the current behavior? setState callback is not functioning
讨论数 3
react
创建时间:2018-04-28 14:42:02

input DX improvement opportunity

Do you want to request a feature or report a bug? A feature What is the current behavior? No warning is raised in the fo
讨论数 4
react
创建时间:2018-04-28 11:48:53

The `ref.current` point to the wrong dom node

eg: {this.state.a ? <div ref={this.myRef} className="a"/> : <div className="b"/>} after state.a was set to false,when ac
讨论数 2
react
创建时间:2018-04-28 10:00:43

* { all: initial; } in css is breaking the react app

Hey guys, I have one problem working with any and even simple app of react. Here is the link of jsfield https://jsfiddle
讨论数 4
react
创建时间:2018-04-27 19:33:56

Coverage Support for JSX-Control-Statements

Conditional Rendering Components JSX-Control-Statement produces incorrect coverage in if / else branches. We are using i
讨论数 4
react
创建时间:2018-04-27 14:41:11

onClick event is not firing after enabling button via ref

Do you want to request a feature or report a bug? possible Bug, needs investigation What is the current behavior? When h
讨论数 4
react
创建时间:2018-04-27 07:45:47

Type is invalid. You likely forgot to export your component from the file it's defined in

I posted a SO question and created an issue on the Voyager project but thought I'd also document it here. I'm using comp
讨论数 3
react
创建时间:2018-04-27 07:00:26

Feature request: get a ref of a in memory dom element before mount.

Do you want to request a feature or report a bug? Feature What is the current behavior? currently, there isn't a great w
讨论数 3
react
创建时间:2018-04-26 19:08:01

Calling ReactDOM.render() many many times is slow

Do you want to request a feature or report a bug? Bug (?) What is the current behavior? Calling ReactDOM.render() many m
讨论数 9
react
创建时间:2018-04-26 18:42:43