首页 文章

在子组件的状态之间共享父状态?

提问于
浏览
3

学习React,我正在构建一个简单的计算器 . 组件模型是:

- Calculator
  - Sliders (input[ref=cars])
  - Dashboard (p {this.state.cars})

Sliders 是具有一组输入的组件,应通过父 Calculator 状态转移到 Dashboard .

我的目标是在 Sliders 输入组件更改时更改 Dashboard 中的状态值 .

var Calculator = React.createClass({
  getInitialState: function() {
    return {
      cars: 0
    };
  },
  render: function () {
    return (
      <div className="calculator">
        <Sliders
          cars={this.state.cars}
        />
        <Dashboard
          cars={this.state.cars}
        />
      </div>
    )
  }
});

var Dashboard = React.createClass({
  getInitialState:function () {
    return {
      cars: this.props.cars
    }
  },
  render: function () {
    return (
      <div>
        <h1>Dashboard</h1>
        <p>Cars: {this.state.cars}</p>
      </div>
    )
  }
})

var Sliders = React.createClass({
  getInitialState: function() {
    return {
      cars: this.props.cars
    };
  },
  handleInput: function () {
    var state = {
      cars: this.refs.cars.value
    }
    this.setState(state);
  },
  render: function () {
    return (
      <div className="sliders">
        <input type="text" ref="cars" onChange={this.handleInput} value={this.state.cars}/>
      </div>
    )
  }
})

正如我所知, handleInput() 被触发,因此设置 Sliders 的状态 . 但是,它不是"transfered"对于父母 Calculator 's state as '汽车' . 所以, Calculator 的状态未更新=> Dashboard 状态也未被更新 .

How to share Calculator's parent state between Sliders and Dashboard?

我知道,在SO上有很多类似的问题,但很难找到具体的有用案例,特别是当你在React中完成noob时 . 所以,抱歉复制 .

3 回答

  • 4

    组件不共享状态 . 但是,一个组件的状态可以成为另一个组件的支柱 .

    在您的情况下, cars 应该是 Calculator,Slide 的状态, Dashboard 应该只检索 cars 作为道具 . 如果输入发生更改, Sliders 应通知 Calculator 有关更改,以便它可以更新其状态并重新呈现(这也会导致 SlidersCalculator 更新):

    var Calculator = React.createClass({
      getInitialState: function() {
        return {
          cars: 0
        };
      },
    
      onUpdate: function (cars) {
        this.setState({cars});
      },
    
      render: function () {
        return (
          <div className="calculator">
            <Sliders
              cars={this.state.cars}
              onUpdate={this.onUpdate}
            />
            <Dashboard
              cars={this.state.cars}
            />
          </div>
        )
      }
    });
    
    var Dashboard = React.createClass({
      render: function () {
        return (
          <div>
            <h1>Dashboard</h1>
            <p>Cars: {this.props.cars}</p>
          </div>
        )
      }
    })
    
    var Sliders = React.createClass({
      handleInput: function (event) {
        this.props.onUpdate(event.target.value);
      },
    
      render: function () {
        return (
          <div className="sliders">
            <input type="text" ref="cars" onChange={this.handleInput} value={this.props.cars}/>
          </div>
        )
      }
    })
    

    尽可能少的组件应该具有状态和状态应该尽可能高的树 . 另见Props in getInitialState Is an Anti-Pattern

  • 1

    在React中,您希望拥有一个或多个“智能”组件,它们处理状态和“哑”组件 . “智能”组件将状态转移到“哑”组件 . 还会注入事件处理程序,就像你的情况一样,是一个改变汽车数量的处理程序 . 您的计算器是您的智能组件 . 它还应该具有处理状态变化的功能 .

    handleCarsChange: function( newAmount ) {
      this.setState({ cars: newAmount });
    },
    

    也不要从 propsmore Information)进入初始状态 . 道具可以更改,直接在渲染函数中使用它们,如下所示:

    var Dashboard = React.createClass({
      render: function () {
        return (
          <div>
            <h1>Dashboard</h1>
            <p>Cars: {this.props.cars}</p>
          </div>
        )
      }
    });
    

    或者使用React 14组件函数语法:

    var Dashboard = function(props) {
        return (
          <div>
            <h1>Dashboard</h1>
            <p>Cars: {props.cars}</p>
          </div>
        );
    };
    

    最后但并非最不重要的是给 Sliders 组件一个处理函数来处理状态更改:

    <Sliders
      cars={this.state.cars}
      handleCarsChange={this.handleCarsChange}
    />
    

    并更改 Slider 组件中的 handleInput 函数:

    handleInput: function(value) {
      this.props.handleCarsChange(this.refs.cars.value);
    },
    
  • 1

    将父母作为道具传递给滑块,你不需要汽车作为滑块中的状态 .

    这是一种做法,但FelixKing的答案更好 .

    var Calculator = React.createClass({
      getInitialState: function() {
        return {
          cars: 0
        };
      },
      handleInput: function () {
        var state = {
          cars: this.refs.cars.value
        }
        this.setState(state);
      },
      render: function () {
        return (
          <div className="calculator">
            <Sliders
              cars={this.state.cars} parent={this}
            />
            <Dashboard
              cars={this.state.cars}
            />
          </div>
        )
      }
    });
    
    var Dashboard = React.createClass({
      getInitialState:function () {
        return {
          cars: this.props.cars
        }
      },
      render: function () {
        return (
          <div>
            <h1>Dashboard</h1>
            <p>Cars: {this.state.cars}</p>
          </div>
        )
      }
    })
    
    var Sliders = React.createClass({
      getInitialState: function() {
        return {};
      },
      handleInput: function (value) {
        this.props.parent.handleInput(this.refs.cars.value);
      },
    
      render: function () {
        return (
          <div className="sliders">
            <input type="text" ref="cars" onChange={this.handleInput} value={this.props.cars}/>
          </div>
        )
      }
    })
    

相关问题