简体   繁体   English

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

[英]Share parent state between child components' states?

Learning React, I'm building a simple Calculator. 学习React,我正在构建一个简单的计算器。 Components model is: 组件模型是:

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

Sliders is component with set of inputs, that should be transfered to Dashboard via parent Calculator state. Sliders是具有一组输入的组件,应通过父Calculator状态传输到Dashboard

My goal is to make state value in Dashboard change on Sliders s input component change. 我的目标是在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>
    )
  }
})

As I've got, handleInput() is trigged, so state for Sliders is set. 正如我handleInput()handleInput()被触发,因此设置了Sliders状态。 However, it's NOT "transfered" to parent Calculator 's state as 'cars'. 但是,它并没有“转移”到父Calculator的状态为“汽车”。 So, Calculator 's state is not updated => Dashboard state is not udpated too. 所以, Calculator的状态没有更新=> Dashboard状态也没有更新。

How to share Calculator's parent state between Sliders and Dashboard? 如何在Sliders和Dashboard之间共享Calculator的父状态?

I know, there are plenty of similar questions on SO, however it's hard to find the specific helpful case, especially when you're complete noob in React. 我知道,在SO上有很多类似的问题,但很难找到具体的有用案例,特别是当你在React中完成noob时。 So, sorry for duplicating. 所以,抱歉复制。

Components don't share state. 组件不共享状态。 The state of one component can become the props of another component though. 但是,一个组件的状态可以成为另一个组件的支柱。

In your case, cars should be the state of Calculator, and Slide and Dashboard should only retrieve cars as props. 在您的情况下, cars应该是Calculator,的状态Calculator,SlideDashboard应该只检索cars作为道具。 If the input changes, Sliders should notify Calculator about the change so that it can update its state and rerender (which causes Sliders and Calculator to update as well): 如果输入发生变化, 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>
    )
  }
})

As few components as possible should have state and state should be as high up in the tree as possible. 尽可能少的组件应该具有状态和状态应该尽可能高的树。 See also Props in getInitialState Is an Anti-Pattern 另请参见getInitialState中的道具是反模式

Pass parent as a prop to slider, and you wont need cars as a state in sliders. 将父母作为道具传递给滑块,你不需要汽车作为滑块中的状态。

This is one way of doing it, but FelixKing's answer is better. 这是一种做法,但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>
    )
  }
})

In React you want to have one or several "smart" components, that handle state and "dumb" components. 在React中,您希望拥有一个或多个“智能”组件,它们处理状态和“哑”组件。 The "smart" components transfer the state down to the "dumb" component. “智能”组件将状态转移到“哑”组件。 The also inject event handlers, like in your case a handler for changing the amount of cars. 还会注入事件处理程序,就像你的情况一样,是一个改变汽车数量的处理程序。 Your calculator is your smart component. 您的计算器是您的智能组件。 It should also have a function to handle the state change. 它还应该具有处理状态变化的功能。

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

Also don't make your initial state from props ( more Information ). 也不要从props获得初始状态( 更多信息 )。 Props are made to change, use them directly in your render function like so: 道具可以更改,直接在渲染函数中使用它们,如下所示:

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

Or with the React 14 component function syntax: 或者使用React 14组件函数语法:

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

Last but not least give the Sliders component a handler function to deal with the state change: 最后但并非最不重要的是给Sliders组件一个处理状态更改的处理函数:

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

And change the handleInput function in the Slider component: 并更改Slider组件中的handleInput函数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM