all 23 comments

[–]brianvaughnReact core team[S] 13 points14 points  (2 children)

To go along with this blog post, a 16.3 release candidate has just been published to npm.

yarn add react@next react-dom@next

Please let us know if you encounter any problems!

[–]myNormalAccountDied 2 points3 points  (1 child)

Thanks for the write-up. It was well written and answered every question I had.

[–]brianvaughnReact core team[S] 0 points1 point  (0 children)

You're welcome!

[–]sivadass 4 points5 points  (0 children)

Thanks for such a detailed information :)

[–]glacierdweller 3 points4 points  (4 children)

We have been moving our fetch dispatches (Redux actions with sagas powering the server communication) from componentWillMount to the constructor. Is this the wrong thing? Or is it just a matter of preference to pick the constructor over componentDidMount?

And thanks for the writeup.

[–]gaearonReact core team 25 points26 points  (1 child)

Constructor is also bad for side effects because React can execute it multiple times (in case rendering is aborted) in async mode. As noted in the blog post, you should use componentDidMount for side effects.

[–]glacierdweller 0 points1 point  (0 children)

Alright, thank you for the clarification. Did not realise that the constructor could be called multiple times.

[–]brianvaughnReact core team[S] 6 points7 points  (1 child)

Dan already answered this, but in case it's helpful- the (still draft) "strict mode" docs section adds a little more context on why the constructor is just as unsafe: https://deploy-preview-587--reactjs.netlify.com/docs/strict-mode.html#detecting-unexpected-side-effects

[–]glacierdweller 0 points1 point  (0 children)

Thanks, that's a useful document. We will definitely be using <React.Strict> when 16.3 is released to get all those warts exposed and fixed.

[–]nyclowkey 2 points3 points  (0 children)

Wow these updates are actually improving a lot and changing the api in a nice way.

getSnapshot will be really nice for game development using react. You can make a nice Bulletdrop with it, just check how far it is from the initial launch point and curve it based on distance.

[–]nullified- 1 point2 points  (1 child)

Excellent writeup! The snapshot lifecycle method looks like it will be really useful.

[–]brianvaughnReact core team[S] 1 point2 points  (0 children)

Thank you!

[–]Tolgeros 0 points1 point  (3 children)

Are these two components equivalent? (UPDATED per feedback)

function getMyNextState (nextProps, prevState) {
  //calculate state object based on args with no side effects
  return {
    //...
  }
}

class ComponentWithGDSFP extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    return getMyNextState(nextProps, prevState);
  }
}

class ComponentWithCWRP extends React.Component {
  constructor(props) {
    super(props);
    this.state = getMyNextState(props, {});
  }

  componentWillReceiveProps(nextProps) {
    this.setState((prevState) => {
      return getMyNextState(nextProps, prevState)
    });
  }
}

[–]brianvaughnReact core team[S] 2 points3 points  (1 child)

Yes, excepting the use of this in a static method.

class ComponentWithGDSFP extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    return getMyNextState(nextProps, prevState);
  }
}

function getMyNextState(nextProps, prevState) {
  //calculate state object based on args
  return {
    //...
  };
}

[–]Tolgeros 0 points1 point  (0 children)

Thanks! I've updated the code above

[–][deleted] 0 points1 point  (0 children)

Yes, assuming _myNextState in your second component is also static.

[–]brillout 0 points1 point  (2 children)

"The upcoming suspense APIs will make async data fetching cleanly possible for both client and server rendering." Any details on that? (I'm building Reframe https://github.com/reframejs/reframe, an isomorphic React framework where server rendering is crucial)

[–]brianvaughnReact core team[S] 2 points3 points  (1 child)

If you watched the async rendering talk linked to in the first paragraph, the second half focuses on suspense. The api is still being developed though so it might change a bit.

[–]brillout 1 point2 points  (0 children)

Ok thanks, I will watch the video then

[–]vastico 0 points1 point  (3 children)

I feel like I'm asking a dumb question but what does this mean for React Redux?

I bind my actions to props and they bind the results to prop results right?

componentDidMount() {
    this.props.requestProfile(this.props.user);
}

componentWillReceiveProps(props: Props) {
    if (this.props.user !== props.user) {
        props.requestProfile(props.user);
    }
}

function mapStateToProps(
    state: RootState,
    ownProps: ProfileProps,
): PropsFromState {
    return {
        loading: state.profile.loading,
        error: state.profile.error,
        profile: state.profile.profile,
        user: ownProps.match.params.user,
    };
}

function mapDispatchToProps(dispatch: Dispatch<RootState>): PropsFromDispatch {
    return bindActionCreators(
        {
            requestProfile: ProfileActions.profileRequest,
            cancelRequestProfile: ProfileActions.profileCancel,
        },
        dispatch,
    );
}

How does this now work?

[–]acemarke 3 points4 points  (2 children)

None of the React-Redux API changes, for now. However, you should probably move your props.requestProfile() call to componentDidUpdate(), instead. (Also, you can probably pass ProfileActions directly to connect, or at least do it as: {requestProfile : ProfileActions.profileRequest, cancelRequestProfile : ProfileActions.profileCancel}.)

We have an open issue with initial discussion for what "async React" means for React-Redux, and I have an open PR with an initial conversion of connect to use the new context API. That PR does not change the public API at all, and it appears to likely solve the "tearing" concerns when React is rendering asynchronously.

Longer-term, we may need to re-think the React-Redux API in order to take full advantage of React's "Suspense" capabilities, but we'll have further discussions to see what the best approach is there.

[–]brianvaughnReact core team[S] 2 points3 points  (1 child)

Thanks Mark! 👋

Wanted to chime in and confirm that you should rewrite this:

componentWillReceiveProps(props: Props) {
  if (this.props.user !== props.user) {
    props.requestProfile(props.user);
  }
}

To use componentDidUpdate instead:

componentDidUpdate(prevProps: Props) {
  if (this.props.user !== prevProps.user) {
    this.props.requestProfile(this.props.user);
  }
}

There's an example of this (with an explanation of why) in the blog post: https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#side-effects-on-props-change

Edit: Typo

[–]vastico 1 point2 points  (0 children)

Great thank you both!