Reactjs 正确使用React getDerivedStateFromProps
在这个例子中Reactjs 正确使用React getDerivedStateFromProps,reactjs,Reactjs,在这个例子中 类计数器扩展React.Component{ 建造师(道具){ 超级(道具); this.state={count:0}; } 静态getDerivedStateFromProps(下一步,上一步){ console.log(“nextrops”,nextrops,“\nprevState”,prevState) if(nextrops.count!==prevState.count) 返回{count:nextrops.count}; 其他的 返回null; } 手动增量(e)
类计数器扩展React.Component{
建造师(道具){
超级(道具);
this.state={count:0};
}
静态getDerivedStateFromProps(下一步,上一步){
console.log(“nextrops”,nextrops,“\nprevState”,prevState)
if(nextrops.count!==prevState.count)
返回{count:nextrops.count};
其他的
返回null;
}
手动增量(e){
this.setState({count:this.state.count+1})
}
处理过的文件(e){
this.setState({count:this.state.count-1})
}
render(){
返回
+
{this.state.count}
-
;
}
}
类Main扩展了React.Component{
建造师(道具){
超级(道具);
this.state={initialCount:1};
}
手变(e){
this.setState({initialCount:e.target.value})
}
render(){
返回
更改首字母:
}
}
ReactDOM.render(
,
document.getElementById(“根”)
);
预期:
单击+/-按钮和文本框更改必须是更新计数
目前:
主组件将initialCount存储在自己的状态中,并将初始计数传递给子计数器组件
若从textbox触发handleChange并更新initialCount,则子计数器组件也会正确更新,因为getDerivedStateFromProps静态方法提供了这一点
但通过handleIncrease和HandleDecrese方法更新局部状态来改变计数器组件中的计数值是不可能的
问题是getDerivedStateFromProps这次重新触发并重置计数值。但我并没有预料到这一点,因为计数器组件本地状态更新父主组件并没有更新。不安全组件将以这种方式接收道具
总结:我的getDerivedStateFromProps使用不正确,或者我的场景有其他解决方案
此版本适用于componentWillReceiveProps我不确定我是否理解正确,但如果您想将该道具用作初始值的“种子”,以便在构造函数中执行此操作,并且您甚至不需要
getDerivedStateFromProps
。实际上,您不需要复制状态:
class Counter extends React.Component {
render() {
return <div>
<button onClick={this.props.handleIncrease}>+</button>
{this.props.count}
<button onClick={this.props.handleDecrease}>-</button>
</div>;
}
}
class Main extends React.Component {
constructor(props) {
super(props);
this.state = { count: 1 };
}
handleIncrease() {
this.setState(prevState => ({count: prevState.count + 1}))
}
handleDecrease() {
this.setState(prevState => ({count: prevState.count - 1}))
}
render() {
return (
<div>
<Counter count={this.state.count} />
<hr/>
Change initial:
<input
type="number"
handleIncrease={this.handleIncrease.bind(this)}
handleDecrease={this.handleDecrease.bind(this)}
count={this.state.count}
/>
</div>
)
}
}
类计数器扩展React.Component{
render(){
返回
+
{this.props.count}
-
;
}
}
类Main扩展了React.Component{
建造师(道具){
超级(道具);
this.state={count:1};
}
handleIncrease(){
this.setState(prevState=>({count:prevState.count+1}))
}
HandleDecrese(){
this.setState(prevState=>({count:prevState.count-1}))
}
render(){
返回(
更改首字母:
)
}
}
像您这样尝试将状态“同步”到道具,极易出错,并导致应用程序出现错误
事实上,甚至你的电脑也有一个bug。如果更频繁地重新渲染父组件,将丢失用户输入 这是一本书。 增加计数器,然后单击“演示错误”,它将吹走计数器。但是这个按钮的
setState
应该是完全不相关的
这说明了为什么尝试将状态同步到道具是个坏主意,应该避免
相反,请尝试以下方法之一:
键来从父组件重置子组件状态
中描述了这两种方法。这篇博文包含了详细的示例和演示,因此我强烈建议您查看。谢谢Tomasz。你的建议是另一种解决方案,但我不能在现实世界中使用它。组件必须使用自己的事件处理程序更新自己的状态。
class Counter extends React.Component {
render() {
return <div>
<button onClick={this.props.handleIncrease}>+</button>
{this.props.count}
<button onClick={this.props.handleDecrease}>-</button>
</div>;
}
}
class Main extends React.Component {
constructor(props) {
super(props);
this.state = { count: 1 };
}
handleIncrease() {
this.setState(prevState => ({count: prevState.count + 1}))
}
handleDecrease() {
this.setState(prevState => ({count: prevState.count - 1}))
}
render() {
return (
<div>
<Counter count={this.state.count} />
<hr/>
Change initial:
<input
type="number"
handleIncrease={this.handleIncrease.bind(this)}
handleDecrease={this.handleDecrease.bind(this)}
count={this.state.count}
/>
</div>
)
}
}