![](/img/trans.png)
[英]React.js Can I use array.map within componentDidMount() on an array returned from an axios request?
[英]In React.js should I make my initial network request in componentWillMount or componentDidMount?
在 react 文档中,它建议在componentDidMount
方法中进行初始网络请求:
componentDidMount()
在组件安装后立即调用。 需要 DOM 节点的初始化应该在这里进行。 如果您需要从远程端点加载数据,这是实例化网络请求的好地方。 在此方法中设置状态将触发重新渲染。
如果componentWillMount
被渲染组件之前调用,是不是更好,使请求,并在这里设置的状态? 如果我在componentDidMount
这样做,则呈现组件,发出请求,更改状态,然后重新呈现组件。 为什么在呈现任何内容之前提出请求不是更好?
您应该在componentDidMount
执行请求。
如果在渲染组件之前调用componentWillMount,那么在这里发出请求并设置状态不是更好吗?
不,因为无论如何,在组件呈现时请求都不会完成。
如果我在componentDidMount中执行此操作,则会呈现组件,发出请求,更改状态,然后重新呈现组件。 为什么在呈现任何内容之前提出请求更好?
因为任何网络请求都是异步的 。 除非你缓存了数据,否则无论如何都无法避免第二次渲染(在这种情况下,您根本不需要触发请求)。 通过先前触发它,你无法避免第二次渲染。 它无济于事。
在React的未来版本中,我们希望componentWillMount
在某些情况下会多次触发,因此您应该将componentDidMount
用于网络请求 。
您应该使用componentDidMount
。
为什么在呈现任何内容之前提出请求更好?
因为:
componentWillMount
(如果适用) 但是,如果您要问,在componentWillMount
启动请求是不是更好(没有实际处理它),我肯定会说是(ES6),我自己这样做偶尔会从加载中减少几毫秒时间:
componentWillMount() {
// if window && window.XMLHttpRequest
if (!this.requestPromise) {
this.requestPromise = new Promise(resolve => {
// ... perform request here, then call resolve() when done.
});
}
}
componentDidMount() {
this.requestPromise.then(data => ...);
}
这将在componentWillMount
期间开始预加载您的请求,但请求仅在componentDidMount
处理,无论是当时已完成还是仍在进行中。
您应该在componentDidMount中发出请求,因为不应在componentWillMount中进行副作用请求。 可以在componentWillMount中设置setState,如果在componentDidMount中设置了state,则会立即触发第二次重新渲染。
你会读到它是一个反模式(UGHHH)并且一些短信禁止它(eslint-react-plugin),但是我不会非常注意它,因为有时它是与DOM交互的唯一方式。 您可以在willMount中设置默认状态,也可以在方法属性(state = {})中设置默认状态,如果您正在使用关联的babel阶段
正如您所说,组件将只渲染一次,但这很好,因为您可以显示某种Loader或资源正在加载的任何其他形式的信息。
class MyComp extends Component {
// What I do with stage 0
state = { mystate: 1 }
// What you might want to do if you're not
// on the experimental stage, no need to do
// the whole constructor boilerplate
componentWillMount() {
this.setState({ mystate: 1 });
}
componentDidMount() {
dispatch(yourAction());
// It's fine to setState here if you need to access
// the rendered DOM, or alternatively you can use the ref
// functions
}
render() {
if (!this.props.myCollection) return <Loader />
return (
<div> // your data are loaded </div>
)
}
}
在 render 方法之前避免在生命周期钩子中获取的真正原因是因为 React 社区计划使 render 方法调用异步。
在此处查看 gaeron 的回复: https : //github.com/reactjs/reactjs.org/issues/302
现在这意味着在渲染之前在任何生命周期方法中放置一个异步操作,如 fetch(或任何与此相关的异步操作),将干扰渲染过程。
所以不像你今天想象的同步执行:
1. 构造函数<< 想象在这里触发 fetch() >> => 2. getDerivedStateFromProps << fetch 完成,回调通过事件循环添加到回调队列 >> => 3. render => 4. componentDidMount => 5. 回调执行添加它们的顺序,以便获取回调现在运行。
它会是这样的:
1. 构造函数<< 想象在这里触发 fetch() >> => 2. getDerivedStateFromProps << 同时,获取完成并且回调被排队 >> << 想象在这里触发异步 render() 。 它的回调也被排队 >> => 回调按照它们添加的顺序执行3. 所以 fetch 回调首先运行=> 4. 渲染回调运行=> 5. componentDidMount
这种干扰可能会导致状态更改被还原,因为渲染可能会应用一个较早的状态来覆盖由 fetch 所做的更改。
另一个原因是,componentDidMount 生命周期保证了相应组件在 DOM 上的存在,如果 fetch 尝试在 DOM 可用或更新之前对其进行操作,则可能导致应用程序显示错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.