[英]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,
而Slide
和Dashboard
应该只检索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
有关更改,以便它可以更新其状态并重新呈现(这会导致Sliders
和Calculator
也更新):
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.