Pen*_*ica 10 javascript lifecycle reactjs react-native redux
使用React和Redux,假设您有一个将请求发送到外部API的组件方法.
import React, { Component } from 'react';
import { connect } from 'react-redux';
class MyComp extends Component {
boolUpdate (val) {
fetch('http://myapi.com/bool', { val });
}
shouldComponentUpdate (nextProps) {
return false;
}
render () {
return <h1>Hello</h1>;
}
}
const mapStateToProps = ({ bool }) => ({ bool });
export default connect(mapStateToProps)(MyComp);
Run Code Online (Sandbox Code Playgroud)
现在假设您希望boolUpdate()每次调整boolprop时调用,但这不应该触发组件更新,因为组件的渲染中没有任何内容受到影响.
在React中执行此操作的最佳方法是什么?
直到最近,人们常常做类似的事情:
componentWillReceiveProps (nextProps) {
if (nextProps.bool !== this.props.bool) this.boolUpdate(nextProps.bool);
}
Run Code Online (Sandbox Code Playgroud)
但是从React v16.3开始componentWillReceiveProps()已被弃用.在这个例子中,我们也不能使用它们componentDidUpdate(),因为shouldComponentUpdate()可以防止这种情况发生.并且getDerivedStateFromProps()是静态方法,因此它无权访问实例方法.
因此,我们留下的唯一选择似乎是使用shouldComponentUpdate()自己.有点像:
shouldComponentUpdate (nextProps) {
if (nextProps.bool !== this.props.bool) this.boolUpdate(nextProps.bool);
return false;
}
Run Code Online (Sandbox Code Playgroud)
这看起来对我来说相当"hacky",而不是为我shouldComponentUpdate()设计的.
有没有人有更好的模式建议?
是否有一种倾听特定道具变化和触发组件方法的首选方法?
谢谢!
如果你想在道具改变时运行一些代码(例如数据获取),那就去做吧componentDidUpdate.
componentDidUpdate(prevProps) {
if (prevProps.id !== this.props.id) {
this.fetchData();
}
}
Run Code Online (Sandbox Code Playgroud)
在您的示例中,这将无效,因为shouldComponentUpdate返回false.我认为这不是一个非常常见的情况,因为通常你仍然想要在道具改变的情况下重新渲染.
例如,如果用户ID更改,您可能希望在加载新用户的数据时显示加载指示符.因此,在这种情况下,避免重新渲染并不是很有用.
但是,如果您完全确定两者都需要阻止重新渲染并且需要执行副作用,例如在道具更改中获取数据,则可以将组件拆分为两个.外部组件将执行数据提取componentDidUpdate并返回<InnerComponent {...this.props} />.内部组件将具有shouldComponentUpdate防止进一步重新呈现的实现.同样,我不希望这是一个常见的情况,但你可以做到这一点.
根据 React文档和github 上的讨论,根据 props 更改获取新数据的地方实际上是componentDidUpdate.
渲染实际上分为两个阶段,一个Render Phase阶段是纯粹的,不会产生副作用,另一个阶段Commit Phase可以运行副作用,使用 DOM 并安排更新。
您可以在 Dan Abramov 的图表中看到很好的解释:\n
丹还提到:
\n\n\n\n\n人们过去常常在 componentWillReceiveProps 中混合这两种不同的东西,这就是为什么我们必须将其分成一个纯方法 (getDerivedStateFromProps) 和一个现有的不纯方法,其中 xe2x80x99 可以产生副作用(组件更新)。
\n
对于解决方案本身,我附上了文档中的示例:
\n\n\n\n当 props 改变时获取外部数据
\n\n下面是一个根据 props 值获取外部数据的组件示例:
\n\n前:
\n\nRun Code Online (Sandbox Code Playgroud)\n\ncomponentDidMount() {\n this._loadAsyncData(this.props.id);\n}\n\ncomponentWillReceiveProps(nextProps) {\n if (nextProps.id !== this.props.id) {\n this.setState({externalData: null});\n this._loadAsyncData(nextProps.id);\n }\n}\n后:
\n\nRun Code Online (Sandbox Code Playgroud)\nstatic getDerivedStateFromProps(nextProps, prevState) {\n if (nextProps.id !== prevState.prevId) {\n return {\n externalData: null,\n prevId: nextProps.id,\n };\n }\n return null;\n }\n\n componentDidMount() {\n this._loadAsyncData(this.props.id);\n }\n\n componentDidUpdate(prevProps, prevState) {\n if (this.state.externalData === null) {\n this._loadAsyncData(this.props.id);\n }\n }\n
| 归档时间: |
|
| 查看次数: |
611 次 |
| 最近记录: |