为啥不能在渲染方法中改变状态。在调用渲染方法之前更改状态的最佳位置是啥
Posted
技术标签:
【中文标题】为啥不能在渲染方法中改变状态。在调用渲染方法之前更改状态的最佳位置是啥【英文标题】:why Can't change the state in the render method. What is the best place to change the state before calling render method为什么不能在渲染方法中改变状态。在调用渲染方法之前更改状态的最佳位置是什么 【发布时间】:2020-08-07 10:22:13 【问题描述】:我正在尝试在 render
方法中进行状态更改,但它显示:
错误:超过最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。 React 限制了嵌套更新的数量以防止无限循环。
class Test extends Component
state =
name:[],
render()
this.setState(name:this.props.data)
return(
<div>
this.state.name.map(e=>(
<h3>e</h3>
))
</div>
);
【问题讨论】:
你不能这样做,因为setState
调用了render,render调用了setState
等等……你最终会陷入死循环。
是的。我想知道在渲染 dom 之前更新状态的最佳位置是什么。
但是你为什么要用已经处于状态的数据来更新状态呢? :) 通常在 React 中,您使用事件处理程序来更新状态。
道具呢?如果有我必须更新到当地状态的道具?
这是一些精简的例子,还是你真的想这样做?直接从道具渲染,即this.props.data.map(e => <h3>e</h3>)
【参考方案1】:
您不能在渲染函数中设置反应状态,但可以在构造函数或大部分组件生命周期函数中设置。
在构造函数中设置一些初始状态
class Test extends Component
constructor(props)
super(props);
this.state =
name: props.data,
;
render()
return (
<div>
this.state.name.map(e => (
<h3>e</h3>
))
</div>
);
或者在生命周期函数中设置状态
class Test extends Component
state =
name: [],
;
componentDidMount()
this.setState( name: this.props.data );
render()
return (
<div>
this.state.name.map(e => (
<h3>e</h3>
))
</div>
);
【讨论】:
【参考方案2】:永远不要在渲染函数中设置状态,因为它可能会产生副作用,最终会产生无限渲染循环。每次状态发生变化时,React 都会调用 render() 函数。在基于用户与 UI 的交互调用的事件处理函数中的渲染函数之外设置状态。
下面的示例是一个基于函数的组件,当用户单击按钮时,它会更改按钮文本。
const DemoApp = (props) =>
const [state, setState] = useState(false);
const handleButtonPress = () =>
setState(true);
return(
<Button
onPress=handleButtonPress
title=state ? 'Pressed' : 'click Here'
color="#841584"
/>
)
【讨论】:
【参考方案3】:可能存在对象的状态取决于不断变化的道具的情况。在这种情况下,getDerivedStateFromProps 方法可以派上用场。在this page 上给出了实现。以下是该方法的使用方法:
constructor(props)
super(props);
this.state = favoritecolor: "red";
static getDerivedStateFromProps(props, state)
return favoritecolor: props.favcol ;
render()
return (
<h1>My Favorite Color is this.state.favoritecolor</h1>
);
ReactDOM.render(<Header favcol="yellow"/>, document.getElementById('root'));
此实现取自上述链接。它当然提供了一种替代方法来更改渲染方法中的状态。
【讨论】:
以上是关于为啥不能在渲染方法中改变状态。在调用渲染方法之前更改状态的最佳位置是啥的主要内容,如果未能解决你的问题,请参考以下文章
Flutter:状态类:为啥不在 setState 方法调用之前改变状态变量,而不是在 setState 方法中