|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: React - Component Lifecycle Mounting |
| 4 | +date: 2018-05-08 |
| 5 | +description: |
| 6 | +img: react-component-lifecycle-updating.png |
| 7 | +tags: [react, reactjs, learn react] |
| 8 | +--- |
| 9 | + |
| 10 | +React updating have 5 methods: |
| 11 | + |
| 12 | +* UNSAFE_componentWillReceiveProps(object nextProps) |
| 13 | + |
| 14 | +* shouldComponentUpdate(object nextProps, object nextState) |
| 15 | + |
| 16 | +* UNSAFE_componentWillUpdate(object nextProps, object nextState) |
| 17 | + |
| 18 | +* componentDidUpdate(object prevProps, object prevState, object snapshot) |
| 19 | + |
| 20 | +* getSnapshotBeforeUpdate(object prevProps, object prevState). |
| 21 | + |
| 22 | +Let go into details: |
| 23 | + |
| 24 | +#### UNSAFE_componentWillReceiveProps |
| 25 | + |
| 26 | +is invoked before a mounted component receives new props. If you need to update the state in response to prop changes (for example, to reset it), you may compare `this.props` and `nextProps` and perform state transitions using `this.setState()` in this method. |
| 27 | + |
| 28 | +If a parent component causes your component to re-render, this method will be called even if props have not changed. Make sure to compare the current and next values if you only want to handle changes. |
| 29 | + |
| 30 | +React doesn’t call UNSAFE_componentWillReceiveProps() with initial props during mounting. It only calls this method if some of component’s props may update. Calling this.setState() generally doesn’t trigger UNSAFE_componentWillReceiveProps(). |
| 31 | + |
| 32 | +#### shouldComponentUpdate(object nextProps, object nextState) boolean |
| 33 | + |
| 34 | +Use `shouldComponentUpdate()` to let React know if a component's output is not affected by the current change in state or props. |
| 35 | + |
| 36 | +is invoked before rendering when new props or state are being received. Defaults to `true`. This method is not called for the initial render or when forceUpdate() is used. |
| 37 | + |
| 38 | +This method return true by default. |
| 39 | + |
| 40 | +Returning false does not prevent child components from re-rendering when their state changes. |
| 41 | + |
| 42 | +If shouldComponentUpdate() returns false, then UNSAFE_componentWillUpdate(), render(), and componentDidUpdate() will not be invoked. |
| 43 | + |
| 44 | +If you determine a component is slow after profiling, you may change it to inherit from `React.PureComponent` which implements shouldComponentUpdate() with a shallow prop and state comparison. |
| 45 | + |
| 46 | +#### UNSAFE_componentWillUpdate(object nextProps, object nextState) |
| 47 | + |
| 48 | +is invoked just before rendering when new props or state are being received. Use this to perform preparation before an update occurs. This method is not called for the initial render. |
| 49 | + |
| 50 | +You cannot call this.setState() here in this method. |
| 51 | + |
| 52 | +You should do anything else in this method (e.g. dispatch a Redux action) that would trigger an update to a React component before `UNSAFE_componentWillUpdate()` returns. |
| 53 | + |
| 54 | +#### componentDidUpdate(object prevProps, object prevState, object snapshot) |
| 55 | + |
| 56 | +is invoked immediately after updating occurs. This method is not called for the initial render. |
| 57 | + |
| 58 | +Use this as an opportunity to operate on the DOM when the component has been updated. This is also a good place to do network requests as long as you compare the current props to previous props (e.g. a network request may not be necessary if the props have not changed). |
| 59 | + |
| 60 | +If your component implements the `getSnapshotBeforeUpdate()` lifecycle, the value it returns will be passed as a third “snapshot” parameter to `componentDidUpdate()`. (Otherwise this parameter will be undefined.) |
| 61 | + |
| 62 | +Noted: `componentDidUpdate()` will not be invoked if shouldComponentUpdate() returns false. |
| 63 | + |
| 64 | +#### getSnapshotBeforeUpdate(object prevProps, object prevState) |
| 65 | + |
| 66 | +is invoked right before the most recently rendered output is committed to e.g. the DOM. It enables your component to capture current values (e.g. scroll position) before they are potentially changed. Any value returned by this lifecycle will be passed as a parameter to `componentDidUpdate()`. |
| 67 | + |
| 68 | +For example: |
| 69 | + |
| 70 | +```javascript |
| 71 | +class ScrollingList extends React.Component { |
| 72 | + constructor(props) { |
| 73 | + super(props); |
| 74 | + this.listRef = React.createRef(); |
| 75 | + } |
| 76 | + |
| 77 | + getSnapshotBeforeUpdate(prevProps, prevState) { |
| 78 | + // Are we adding new items to the list? |
| 79 | + // Capture the scroll position so we can adjust scroll later. |
| 80 | + if (prevProps.list.length < this.props.list.length) { |
| 81 | + const list = this.listRef.current; |
| 82 | + return list.scrollHeight - list.scrollTop; |
| 83 | + } |
| 84 | + return null; |
| 85 | + } |
| 86 | + |
| 87 | + componentDidUpdate(prevProps, prevState, snapshot) { |
| 88 | + // If we have a snapshot value, we've just added new items. |
| 89 | + // Adjust scroll so these new items don't push the old ones out of view. |
| 90 | + // (snapshot here is the value returned from getSnapshotBeforeUpdate) |
| 91 | + if (snapshot !== null) { |
| 92 | + const list = this.listRef.current; |
| 93 | + list.scrollTop = list.scrollHeight - snapshot; |
| 94 | + } |
| 95 | + } |
| 96 | + |
| 97 | + render() { |
| 98 | + return ( |
| 99 | + <div ref={this.listRef}>{/* ...contents... */}</div> |
| 100 | + ); |
| 101 | + } |
| 102 | +} |
| 103 | +``` |
| 104 | + |
| 105 | +In the above examples, it is important to read the `scrollHeight` property in `getSnapshotBeforeUpdate` rather than `componentWillUpdate` in order to support async rendering. With async rendering, there may be delays between “render” phase lifecycles (like `componentWillUpdate` and render) and “commit” phase lifecycles (like `getSnapshotBeforeUpdate` and `componentDidUpdate`). If a user does something like resize the browser during this time, a `scrollHeight` value read from `componentWillUpdate` will be stale. |
0 commit comments