Skip to content

Props shouldn’t be overwritten #967

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

timneutkens
Copy link

@timneutkens timneutkens commented May 8, 2018

I'm not sure what the correct functionality is, either providing the new props vs the old ones / merging them etc. But the change made in 4.1.0 is breaking and should be part of a major version.

It also seems weird to me that componentWillUpdate is called from react-hot-loader 🤔

Fixes vercel/next.js#4299

screen shot 2018-05-08 at 11 21 00

testProps is the old way they were calculated in 4.0.0/4.1.0

nextProps are the new way they were calculated in 4.1.0+

My change brings back the result of testProps rather than nextProps.

@timneutkens
Copy link
Author

timneutkens commented May 8, 2018

Another solution to the problem we're having with styles-jsx is to remove the extra componentWillUpdate

@codecov-io
Copy link

Codecov Report

Merging #967 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #967   +/-   ##
=======================================
  Coverage   88.99%   88.99%           
=======================================
  Files          30       30           
  Lines         727      727           
  Branches      166      166           
=======================================
  Hits          647      647           
  Misses         66       66           
  Partials       14       14
Impacted Files Coverage Δ
src/reconciler/hotReplacementRender.js 89.8% <ø> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b22f37e...a6bbd40. Read the comment docs.

@theKashey
Copy link
Collaborator

It also seems weird to me that componentWillUpdate is called from react-hot-loader 🤔
This is how React-Redux got signal to update wrapped component.

As far as I know - the logic around merging props should correct.

const Switch  = ({flag}) => flag ? <button1 /> : <button2 />;

<Switch flag={0}
// and then
<Switch flag={1}

React will re-render something with flag={1} and that means that we have to work with flag={1}, with a new prop, not the old one.

Look like, you dont need this change. You might need remove side effect on props. So - store the original props, and restore them just after render.

in the same time, I am merging old tree and a new tree. Probably I should use the values used to build existing tree, ie "the old values".

I have to double check.

Meanwhile - could you double check that

const next = instance => {
      // copy over props as long new component may be hidden inside them
      // child does not have all props, as long some of them can be calculated on componentMount.
      const realProps =  instance.props; // <<-------
      const nextProps = {
        ...instance.props,
        ...(child.nextProps || {}),
        ...(child.props || {}),
      }

      if (isReactClass(instance) && instance.componentWillUpdate) {
        // Force-refresh component (bypass redux renderedComponent)
        instance.componentWillUpdate(nextProps, instance.state)
      }
      instance.props = nextProps
      hotReplacementRender(instance, stackChild)
      instance.props = realProps; // <<-----
    }

Fixes your problem. Might be this change should be added.

@timneutkens
Copy link
Author

Meanwhile - could you double check that

Since:

if (isReactClass(instance) && instance.componentWillUpdate) {
        // Force-refresh component (bypass redux renderedComponent)
        instance.componentWillUpdate(nextProps, instance.state)
      }

is still called the result is the same

@timneutkens
Copy link
Author

@theKashey
Copy link
Collaborator

Why changing the props merge order (and why you are getting new values?) fixes the problem?

theKashey added a commit that referenced this pull request May 8, 2018
@theKashey
Copy link
Collaborator

Ok. So what I found:

  1. The merge order was right. There is no difference between child.props and nextProps, they are both is props of Component, just from different sources (lets call it so)
  2. That might be not correct in real, but this is how v4 works and this is how we build out tests.
  3. Your problem is not due to props, but due to how componentWillUpdate called. As long "we are not touching lifecycle events", probably we should call this method with unchanged props.
  4. There were a side effect with soiling component props, I noticed with React 15. The patch will fix it.

See #968

@timneutkens
Copy link
Author

Awesome @theKashey 🏆 ❤️

probably we should call this method with unchanged props

Yeah so this is what was done before (in rhl 3 / 4.0.0/4.0.1), I'll check your branch 👍

@timneutkens
Copy link
Author

#968 fixes this issue.

@timneutkens timneutkens closed this May 8, 2018
@timneutkens timneutkens deleted the fix/styled-jsx-issue branch May 8, 2018 12:17
gregberge pushed a commit that referenced this pull request May 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants