我正在努力做最后一年的反应。我们遵循的约定是进行API调用 componentDidMount
,在数据到来后获取数据和setState。这将确保组件已安装并且设置状态将导致重新呈现组件但我想知道为什么我们不能setState in componentWillMount
要么 constructor
官方文件说:
在安装发生之前立即调用componentWillMount()。它
在render()之前调用,因此在此方法中设置状态
不会触发重新渲染。避免引入任何副作用或
此方法中的订阅。
它说 setting state in this method will not trigger a re-rendering
,这是我在进行API调用时不想要的。如果我能够获取数据并且能够设置状态(假设API调用非常快) componentWillMount
或者在 constructor
并且数据存在于第一个渲染中,为什么我要重新渲染?
如果API调用很慢,那么 setState
将是异步和 componentWillMount
已经返回然后我将能够setState并且应该重新渲染。
总的来说,我很困惑为什么我们不应该在构造函数或componentWillMount中进行API调用。在这种情况下,有人能真正帮助我了解反应是如何起作用的吗?
1。 componentWillMount
并重新渲染
比较这两个 componentWillMount
方法。
一个导致额外的重新渲染,一个没有
componentWillMount () {
// This will not cause additional re-render
this.setState({ name: 'Andrej '});
}
componentWillMount () {
fetch('http://whatever/profile').then(() => {
// This in the other hand will cause additional rerender,
// since fetch is async and state is set after request completes.
this.setState({ name: 'Andrej '});
})
}
。
。
。
2.在哪里调用API调用?
componentWillMount () {
// Is triggered on server and on client as well.
// Server won't wait for completion though, nor will be able to trigger re-render
// for client.
fetch('...')
}
componentDidMount () {
// Is triggered on client, but never on server.
// This is a good place to invoke API calls.
fetch('...')
}
如果要在服务器上进行渲染,并且组件确实需要数据进行渲染,则应在组件外部获取(并等待完成)并通过props传递数据,然后将组件渲染为字符串。
ComponentWillMount
现在那个了 道具和国家都设定了,我们终于进入了生命周期方法的领域
这意味着React期待 state
可用 render
函数将被调用next,如果任何提到的状态变量丢失,代码可能会中断,如果有的话 ajax
。
构造函数
这是您定义的地方。
所以调用ajax不会更新任何状态的值,因为ajax是异步的,构造函数不会等待响应。理想情况下,您应该使用构造函数进行设置 默认/初始 值。
理想情况下,这些函数应该是纯函数,仅取决于参数。瞻 ajax
带来副作用。
是的,功能取决于 state
和使用 this.setState
可以带给你这样的问题(您已在状态中设置值,但在下一个被调用函数中的状态中缺少值)。
这使代码变得脆弱。如果您的API非常快,您可以将此值作为参数传递,并在组件中检查此arg是否可用。如果是,请初始化您的状态。如果没有,请将其设置为默认值。此外,在ajax的成功功能中,您可以检查 ref
这个组件。如果存在,则呈现组件,您可以调用它 state
运用 setState
或任何 setter
(首选)功能。
还记得,当你说的时候 API调用非常快,您的服务器和处理可能处于最佳速度,但您无法确定网络。
如果你只需要在第一次运行时只需要数据,如果你对它没问题。您可以通过调用回调来同步setState。
例如:
componentWillMount(){
this.setState({
sessionId: sessionId,
}, () => {
if (this.state.hasMoreItems = true) {
this.loadItems() // do what you like here synchronously
}
});
}