React学习笔记(三)-组件通信

React学习笔记(三)-组件通信_第1张图片
层级.png

父子组件的通信

  • 1.父 => 子
    父组件向子组件的通信是通过props。较为简单,代码如下
    class Child_1 extends React.Component {
        constructor(...arg) {
            super(...arg)
        }

        render() {
            return 
{this.props.data}
} } class Parent extends React.Component{ constructor(...arg){ super(...arg) } render(){ return } } ReactDOM.render(,document.getElementById('app'));

如果父组件与子组件之间不止一个层级,如 Parent 与 Child_1_1 这样的关系,可通过 ... 运算符(Object 剩余和展开属性),将父组件的信息,以更简洁的方式传递给更深层级的子组件。通过这种方式,不用考虑性能的问题,通过 babel 转义后的 ... 运算符 性能和原生的一致,且上级组件 props 与 state 的改变,会导致组件本身及其子组件的生命周期改变

// 再通过在使用后辈组件时,将props作为数据向后传递
    class Child_1_1 extends React.Component {
        render() {
            return 

孙:{this.props.msg}

} } class Child_1 extends React.Component { constructor(...arg) { super(...arg) } render() { return
子:{this.props.data}
} } class Parent extends React.Component { constructor(...arg) { super(...arg) } render() { return } } ReactDOM.render(, document.getElementById('app'));
  • 2.子 => 父
    子组件向父组件通讯,同样也需要父组件向子组件传递 props 进行通讯,只是父组件传递的,是作用域为父组件自身的函数,子组件调用该函数,将子组件想要传递的信息,作为参数,传递到父组件的作用域中。
// 代码一 有bug
    class Child extends React.Component {
        constructor(...args) {
            super(...args);
            this.state = {
                data: 'the data from child'
            }
        }
        static getDerivedStateFromProps(nextProps,preState) {
            nextProps.fn(preState.data)
        }
        render() {
            // this.props.fn(this.state.data);
            return 
Child:{this.state.data}
} } class Parent extends React.Component { constructor(...args) { super(...args); this.state = { getData: '' } } fn(data) { console.log('子组件调用了fn方法!'); this.setState({ getData: data }) } render() { return (
Parent:{this.state.getData}
) } } ReactDOM.render(, document.getElementById('app'));

(此处报错ReferenceError: state is not defined 已解决。原因:在constructor中的state应该是this.state={}。在constructor外的state可以直接state = {}
(此时又报错Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.原因:子组件改变了父组件的state,触发了父组件的re-render,导致父组件重新渲染,此时渲染到了子组件,子组件再次调用函数改变父组件state,又重新触发re-render,造成死循环。解决方法:在父组件的setState外加判断,当this.state.getDate和调用时的data相同时不执行setState避免重复设置状态)

// 代码二 
    class Child extends React.Component {
        constructor(...args) {
            super(...args);
            this.state = {
                data: 'the data from child'
            }
        }

        static getDerivedStateFromProps(nextProps, preState) {
            nextProps.fn(preState.data)
        }

        render() {
            return 
Child:{this.state.data}
} } class Parent extends React.Component { constructor(...args) { super(...args); this.state = { getData: '' } } fn(data) { if (this.state.getData !== data) { this.setState({ getData: data }) } } render() { return (
Parent:{this.state.getData}
) } } ReactDOM.render(, document.getElementById('app'));

上下两段代码中,无论在render还是getDerivedStateFromProps阶段执行fn结果都是一样的。附上本项目启动后的生命周期


React学习笔记(三)-组件通信_第2张图片
life.PNG

【死循环的另一种常见情况】
只要进入了某一个阶段,则这个阶段的生命周期都会做。
所以在Updaing整个阶段中,5个生命周期:componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate中,都不能操作state!如果操作了state,再次导致更新,所有生命周期再次执行,导致死循环 。

兄弟组件的通信

  • 1.利用父组件实现兄弟组件间的通信
    这种方法相对简单,C1通过调用父组件的函数向父组件传递数据,父组件得到数据后再通过props传递给C2
    // 利用父组件实现兄弟组件的通信
    class Child1 extends React.Component {
        constructor(...args) {
            super(...args)
            this.state = {
                msg: 'the message form child-1'
            }
        }

        render() {
            this.props.fn(this.state.msg)
            return (
                
Child-1:{this.state.msg}
) } } class Parent extends React.Component { constructor(...args) { super(...args) this.state = { data: '' } } fn(msg) { if (msg !== this.state.data) { this.setState({ data: msg }) } } render() { return (
Parent:{this.state.data}
) } } class Child2 extends React.Component { constructor(...args) { super(...args) } render() { return (
Child-2:{this.props.msg}
) } } ReactDOM.render(, document.getElementById('app'));

然而,这个方法有一个问题,由于 Parent 的 state 发生变化,会触发 Parent 及从属于 Parent 的子组件的生命周期,所以我们在控制台中可以看到,在各个组件中的 componentDidUpdate 方法均被触发。

你可能感兴趣的:(React学习笔记(三)-组件通信)