反应属性没有冒泡

时间:2018-01-24 09:40:38

标签: reactjs

我有一个反应组件(父),其状态为另一个反应组件(子) 传递下来的父母不是对孩子的道具。 但是如果我在传递的属性上执行setState,它就不会在子节点中更新。我如何使状态的变化反映在子节点中? 见代码:

        class Child extends React.Component {
            constructor(props) {
                super(props)    
            }

            render() {
                return (
                <div>
                    {this.props.x}
                </div>
                )
            }
        }

        class Parent extends React.Component {
            constructor(props) {
                super(props)

                this.state = {x: 1, intervalID: 0, currentScreen: <Child x={0} />}
            }

            componentDidMount() {
                let self = this
                let intervalID = setInterval(function() {
                    self.setState({x: self.state.x+1})
                }, 1000)
                self.setState({intervalID: intervalID, currentScreen: <Child x={self.state.x} />})
            }

            render() {

                return (
                <div>
                    {this.state.currentScreen}
                </div>
                )
            }
        }

        ReactDOM.render(<Parent />, document.getElementById('app'))

3 个答案:

答案 0 :(得分:0)

您的子组件未更新,因为父组件componentDidMount的生命周期仅在安装时调用一次。

如果您需要定期更新状态,可以执行以下操作:

import React, { Component } from 'react';
import { render } from 'react-dom';

class Child extends Component {
  constructor(props) {
    super(props)
  }

  render() {
    return (
      <div>
        {this.props.x}
      </div>
    )
  }
}

class Parent extends Component {
  constructor(props) {
    super(props)

    this.state = { x: 1, intervalID: 0 }
  }

  componentDidMount() {
    let self = this
    let intervalID = setInterval(function () {
      self.setState({ x: self.state.x + 1 })
    }, 1000)
    self.setState({ intervalID: intervalID })
  }

  render() {

    return (
      <div>
        <Child x={this.state.x}/>
      </div>
    )
  }
}

render(<Parent />, document.getElementById('root'))

对于你的情况,只有当setState完成时,它才会再次调用render,它会将最新的x值传递给子组件。

您可以在stackblitz

上查看实时工作示例

答案 1 :(得分:0)

在州内维护JSX是一种不好的做法。将所有JSX移动到render()并使用状态变量来管理状态,如下所示(为简洁起见,仅显示 Parent 组件代码)。

为了清晰起见,不再使用let self=this而是使用箭头功能。

请注意,如果新状态取决于之前的状态,则需要在设置状态时使用updater function。这是因为React对状态进行批量更新。有关详细信息,请参阅official documentation

class Parent extends React.Component {
  constructor(props) {
    super(props)
    this.state = { x: 1 }
  }

  componentDidMount() {
    setInterval(() => {
      this.setState((prevState, props) => {
        return { x: prevState.x + 1 };
      });
    },3000)
  }

  render() {

    return (
      <div>
        <Child x={this.state.x} />
      </div>
    )
  }
}

ReactDOM.render(<Parent />, document.getElementById('root'))

以上功能将每3秒更新x的值。以下是一个工作示例

https://codesandbox.io/s/2677zoo4p

答案 2 :(得分:0)

以下代码正常运作。

import React from 'react';
import ReactDOM from 'react-dom';

class Child extends React.Component {
    render() {
        return (
        <div>
            {this.props.x}
        </div>
        )
    }
}

class Parent extends React.Component {
    constructor(props) {
        super(props)

        this.state = {x: 1, intervalID: 0, currentScreen: <Child x={0} />}
    }

    componentDidMount() {
        let intervalID = setInterval(() => {
            const x = this.state.x + 1;
            this.setState({
                x: x,
                currentScreen: <Child x={x} />
            });
        }, 1000)
        this.setState({intervalID: intervalID, currentScreen: <Child x={this.state.x} />})
    }

    render() {

        return (
        <div>
            {this.state.currentScreen}
        </div>
        )
    }
}

ReactDOM.render(<Parent />, document.getElementById('root'))