React:props赋值给state出现的问题

import { render } from 'react-dom'
import React from 'react'

class Child extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      list: props.list
    }
  }

  handleCilck = () => {
    this.setState({
      list: this.state.list.concat({ name: '小明' })
    })
  }

  render() {
    return (
      
{this.state.list.map((item, index) => { return

Hello, {item.name}

})}
) } } class Parent extends React.Component { constructor(props) { super(props) this.state = { list: [{ name: '小红' }, { name: '小兰' }] } } handleClick = () => { this.setState({ this.setState({list: [{name: '小绿'}]}) }) } render() { return (
; ;
) } } export default Parent;

我们想得到的结果是子组件根据父组件传的props值的改变来渲染内容,但是结果显示子组件渲染的列表并不会跟随父组件更新。

子组件会执行render,但是渲染出来的列表数据不变。
**原因:**父组件更新导致子组件更新时,子组件的生命周期执行顺序如下:
React:props赋值给state出现的问题_第1张图片
也就是说子组件刷新的时候,不再执行constructor,当然也就不会对state重新赋值,所以子组件虽然执行了render,但是渲染数据不变。

解决方案:
1、在componentWillReceiveProps中重新对state赋值。

componentWillReceiveProps在初始化render的时候不会执行,它会在Component接受到新的状态(Props)时被触发,一般用于父组件状态更新时子组件的重新渲染。
componentWillReceiveProps中想作任何变更最好都将两个状态进行比较,假如状态有异才执行下一步。不然容易造成组件的多次渲染,并且这些渲染都是没有意义的。

componentWillReceiveProps(nextProps) {
	if(nextProps.list !== this.props.list){
		this.setState({
      		list: nextProps.list
   	    })
    } 
}
2、使用getDerivedStateFromProps

这个生命周期函数是为了替代componentWillReceiveProps存在的,所以在你需要使用componentWillReceiveProps的时候,就可以考虑使用getDerivedStateFromProps来进行替代了。

getDerivedStateFromProps是一个静态函数,也就是这个函数不能通过this访问到class的属性,也并不推荐直接访问属性。而是应该通过参数提供的nextProps以及prevState来进行判断,根据新传入的props来映射到state。

需要注意的是,如果props传入的内容不需要影响到你的state,那么就需要返回一个null,这个返回值是必须的,所以尽量将其写到函数的末尾。

static getDerivedStateFromProps(nextProps){
		// 当传入的list 发生变化的时候,更新state
        if(nextProps.list !== this.props.list){
			this.setState({
	      		list: nextProps.list
	   	    })
    	} 
    	// 否则,对于state不进行任何操作
    	return null
   }

参考链接:
https://zhuanlan.zhihu.com/p/83623692
https://juejin.im/post/5cf0e961f265da1b8e7085e6

你可能感兴趣的:(React)