react中state、props以及两者的区别

4,239

state

基本定义

state是组件内部的状态(数据),不能够直接修改,必须要通过setState来改变值的状态,从而达到更新组件内部数据的作用。

props

基本定义

props是指组件间传递的一种方式,props自然也可以传递state。由于React的数据流是自上而下的,所以是从父组件向子组件进行传递;另外组件内部的this.props属性是只读的不可修改。

代码示例

// 父组件
import stateJj from './stateJj.js'; // 引入子组件
class stateJjFather extends React.Component {
    constructor(props) {
        super(props);
        // 设置state的默认值 且只能在constructor中设置
        this.state = {
            mes: '给子组件的信息',
            obj: {
                
            },
            arr: []
        }
    }
    fun(e) {
        
    }
    render() {
        const {mes, obj, arr} = this.state;
        return (
            <div>
                // 不写箭头函数 this指向会发生错误 也可以使用bind的方式绑定this
                <stateJj name={'给子组件的信息'} name1={mes}  fun={(e) => this.fun(e)}  obj={obj}  arr={arr} />  
            </div>
        );
    }
}
// 子组件
class stateJj extends React.Component {
    constructor(props) {
        super(props);
        this.props; // 这里面就有父组件传的值
        // 设置 默认state
        this.state = {
            text: props.initialValue || 'placeholder'
        };

        // ES6 类中函数必须手动绑定
        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(event) {
        this.setState({
            text: event.target.value
        });
    }

    render() {
        return (
            <div>
                {mes}
            </div>
        );
    }
}
// 设置props值的类型
stateJj.propTypes = {
    optionalArray: PropTypes.array,
    optionalBool: PropTypes.bool,
    optionalFunc: PropTypes.func,
    optionalNumber: PropTypes.number,
    optionalObject: PropTypes.object,
    optionalString: PropTypes.string,
    optionalSymbol: PropTypes.symbol,   // 目前可以声明的所有变量类型
};
// 设置默认的props值
stateJj.defaultProps = {
};

props的特性

  1. 只读性

props经常被用作渲染组件和初始化状态,当一个组件被实例化之后,它的props是只读的,不可改变的。如果props在渲染过程中可以被改变,会导致这个组件显示的形态变得不可预测。只有通过父组件重新渲染的方式才可以把新的props传入组件中。

  1. 不变性

只能通过外部组件主动传入新的props来重新渲染子组件,否则子组件的props以及展现形式不会改变。

通过setState改变state的值

state不同于props的一点是,state是可以被改变的。不过,不可以直接通过this.state=的方式来修改,而需要通过this.setState()方法来修改state。

注意: state 只能在constructor中设置默认值

setState基础用法

通常我们通过ajax请求数据后,在走通请求后,通过setState方法改变state的值,React会更新组件的数据状态state,并且重新调用render方法,也就是会对组件进行重新渲染。

    // 这是封装的fetch方法
    APIHelper.shipInfo({
        shipName: value
    }).then(res => {
        let datas = res.data;
        this.setState({
            dataList: datas,
        })
    }).catch(err => {
        this.setState({
            isLoading: false,ue
        });
    })

setState使用的注意事项

  1. 当我们调用这个函数的时候,React.js 会更新组件的状态 state ,并且重新调用 render 方法,然后再把 render 方法所渲染的最新的内容显示到页面上
  2. React.js 并不会马上修改 state。而是把这个对象放到一个更新队列里面,稍后才会从队列当中把新的状态提取出来合并到 state 当中,然后再触发组件更新,也就是说setState的更新是异步的

即时更新state的方法:

  1. 使用setState的第二个参数
    setState({
       mes: '123' 
    }, function() {
        console.log(this.state.mes); // 此时state中的mes为 123
    });
  1. 使用react监测不到的方法调用setState
    setTimeOut(function() {
        setState({
            mes: 123
        })
    }, 500); // 里面的值会即时更新 因为react并能监测定时器、延时器里面的方法
    
    // 在调用事件的时候使用原生事件
    componentDidMount() {
      document.querySelector('#btn-raw').addEventListener('click', this.onClick);
    }
    onClick() {
      this.setState({count: this.state.count + 1});
      console.log('# this.state', this.state);  // 打印的为即时值
    }
    // ......
    render() {
      console.log('#enter render');
      return (
        <div>
          <div>{this.state.count}
            <button id="btn-raw">Increment Raw</button>
          </div>
        </div>
      )
    }
    

总结

  1. props用于定义外部接口,state用于记录内部状态
  2. props的赋值在于外部世界使用组件,state的赋值在于组件内部
  3. 组件不应该改变props的值,而state存在的目的就是让组件来修改的
  4. state 只能在constructor中设置默认值
  5. setState修改state的值是异步的