state更新不生效之——派生状态

原因

一个派生 state 值[num]也被 setState 方法更新时,这个值就不是一个单一来源的值了。

误解

getDerivedStateFromProps 和 componentWillReceiveProps 只会在 props “改变”时才会调用。实际上只要父级重新渲染时,这两个生命周期函数就会重新调用,不管 props 有没有“变化”。

在这两个方法内直接复制props 到 state 是不安全的。这样做会导致 state 后没有正确渲染。

demo 示例

  • 如下代码,可以自己本地跑一遍,无论怎么点击按钮,数字一直是1,setState并未生效

  
    class Children extends React.Component  {
    
    
    	constructor(props) {
    
    
		    super(props)
		    this.state = {
    
    
		      num: props.num
		    }
		}
		handleClick = () => {
    
    
        	this.setState({
    
     num: this.state.num+1 });   
        };
        componentWillReceiveProps(nextProps) {
    
    
        	// This will erase local state updates!
        	this.setState({
    
     num: nextProps.num });   } 
        }
    
        render() {
    
    
        	return (
          		<div>
            		<input type='button' value='点击+1' onClick={
    
    this.handleClick} />
            		<span>{
    
    this.state.num}</span>
          		</div>
        	)
    	}
    }  
  
    class Fa extends React.Component {
    
    
    	constructor(props) {
    
    
		    super(props)
		    this.state = {
    
    
		      count: 0
		    }
		}
        componentDidMount() {
    
    
	        this.interval = setInterval(
	          () =>
	            this.setState(prevState => ({
    
    
	              count: prevState.count + 1
	            })),
	          1000
	        );   
        }
    
        componentWillUnmount() {
    
    
        	clearInterval(this.interval);   
        }
    
        render() {
    
    
	        return (
	          <Fragment>
	            <Children num={
    
    1} />
	          </Fragment>
	        );   
	     } 
    }
    


一般派生状态的bug不外乎如下两种情况

  1. 直接复制 props 到 state 上;
  2. 如果 props 和 state 不一致就更新 state

解决方法见官方文档派生状态bug解决方案

猜你喜欢

转载自blog.csdn.net/m0_38073011/article/details/115010198