构造函数与组件WillMount; componentWillMount 能做啥而构造函数不能?
Posted
技术标签:
【中文标题】构造函数与组件WillMount; componentWillMount 能做啥而构造函数不能?【英文标题】:constructor vs componentWillMount; what a componentWillMount can do that a constructor cannot?构造函数与组件WillMount; componentWillMount 能做什么而构造函数不能? 【发布时间】:2017-04-11 05:07:08 【问题描述】:据我所知,componentWillMount
唯一能做而constructor
不能做的就是打电话给setState
。
componentWillMount()
setState( isLoaded: false );
由于我们还没有调用render
,componentWillMount
中的setState
将在我们进入第一个render()
传递之前准备状态对象。这与constructor
所做的基本相同:
constructor(props)
super(props);
this.state = isLoaded: false ;
但我看到另一个用例componentWillMount
很有用(在服务器端)。
让我们考虑一些异步的东西:
componentWillMount()
myAsyncMethod(params, (result) =>
this.setState( data: result );
)
这里我们不能使用constructor
作为对this.state
的赋值不会触发render()
。
componentWillMount
中的setState
怎么样?根据React docs:
componentWillMount()
在安装发生之前立即调用。它 在render(
) 之前调用,因此在此方法中设置状态将 不会触发重新渲染。避免引入任何副作用或 此方法中的订阅。
所以,在这里我认为 React 将使用新的状态值进行第一次渲染并避免重新渲染。
问题 1:这是否意味着,在 componentWillMount
内部,如果我们在异步方法的回调(可以是 Promise 回调)中调用 setState
,React 会阻止初始渲染 直到回调被执行?
在客户端上进行此设置(是的,我在服务器端渲染中看到了该用例),如果我假设上述情况属实,那么在我的异步方法完成之前我将看不到任何东西。
我是否遗漏了任何概念?
问题 2:我可以仅使用 componentWillMount
而不是使用 constructor
和 componentDidMount
实现的任何其他用例吗?
【问题讨论】:
问题 1:这是否意味着,在 componentWillMount 内部,如果我们在异步方法的回调(可以是 Promise 回调)中调用 setState,React 会阻塞初始渲染,直到回调被执行?" 肯定不是——它怎么知道?React 很强大,但并不神奇。 我想知道我的第一个问题是否完全有效,否则我想知道componentWIllMount
的真实用例是什么。很抱歉在一个问题中问了两个问题。我不想在另一个问题中重复我所有的研究故事。 :)
【参考方案1】:
这是否意味着,在 componentWillMount 内部,如果我们在一个 async 方法的回调(可以是 promise 回调),React 块 执行回调之前的初始渲染?
不,请参阅here。
以下代码不会阻止渲染(请记住,无论如何调用 setState 都是一种反模式)
componentWillMount: function()
new Promise((resolve, reject) =>
setTimeout(()=>
resolve();
, 2000)
).then(() => this.setState( promiseResult: 'World' ));
,
问题 2:我可以使用哪些其他用例来实现 仅 componentWillMount,但不使用构造函数和 componentDidMount?
不,对于 ES6 类,您可以丢弃 componentWillMount。只有使用React.createClass(... )
时才需要
编辑:显然,我错了。感谢@Swapnil 指出这一点。这是discussion。
如果constructor
中存在修改另一个组件中的状态的副作用,React 会抛出警告,因为它假定constructor
本身中的setState
可能在render()
期间被调用。因此,constructor
没有副作用。
如果您在componentWillMount
中执行此操作,则不会出现任何错误。另一方面,来自 facebook 的人也反对 componentWillMount
中的副作用。因此,如果您没有任何副作用,您可以使用constructor
而不是componentWillMount
。对于副作用,建议使用componentDidMount
而不是componentWillMount
。
无论哪种方式,您都不需要componentWillMount
。
【讨论】:
对于 ES6,如果我使用 Redux 并希望在初始加载时调度一个动作,建议在 componentWillMount 而不是构造函数中调度动作。 It says that over here 还有一件事。我的名字是 Swapnil 而不是 Swapnii :p 我需要眼镜;-) @leo,在你分享的小提琴中,我在render()
中放了一个日志。我观察到的是,React 在第一次渲染时会渲染一个“Hello”。然后在 2s 后发生超时,从componentWillMount
调用setState
。 React 更新了 DOM 上的新状态值,尽管它没有重新渲染!!这对我来说很神秘!它是如何在不重新渲染的情况下更新 DOM 的? (我很确定,我在这里遗漏了一些关于 React 的内容)。
对不起,是我的眼睛出卖了我!!你是对的,是的,它重新渲染。哦,现在我明白了,setState
不是从 componentWillMount
闭包中调用的。它是从另一个作用域调用的,即回调函数的 env;从而触发了渲染。所以反应文档是正确的,componentWillMount
内部的setState
不会触发重新渲染:)以上是关于构造函数与组件WillMount; componentWillMount 能做啥而构造函数不能?的主要内容,如果未能解决你的问题,请参考以下文章