Javascript 在“与对象反应”中的子对象之间共享状态
当我尝试从一个孩子更新所有孩子的状态时,我遇到了一些问题,下面是我的代码示例。其思想是自动更新其中一个组件的所有组件 我是react的新手,我才用了一个星期,所以可能这一切都是误会Javascript 在“与对象反应”中的子对象之间共享状态,javascript,reactjs,state,Javascript,Reactjs,State,当我尝试从一个孩子更新所有孩子的状态时,我遇到了一些问题,下面是我的代码示例。其思想是自动更新其中一个组件的所有组件 我是react的新手,我才用了一个星期,所以可能这一切都是误会 从“React”导入React; 从'react dom'导入{render}; 从“./Hello”导入Hello; 类父类扩展了React.Component{ 建造师(道具){ 超级(道具); 此.state={ filedStr:“一些文本”, fieldObj:{ 字段1:是的, 字段2:正确 } } }
从“React”导入React;
从'react dom'导入{render};
从“./Hello”导入Hello;
类父类扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
filedStr:“一些文本”,
fieldObj:{
字段1:是的,
字段2:正确
}
}
}
updObj=(其中,val)=>{
this.setState(prevState=>({
fieldObj:{
…prevState.fieldObj,
[哪个]:瓦尔,
},
}));
};
render(){
返回(
父母亲
父组件状态中的值:{this.State.fieldObj.field1?1:0}:{this.State.fieldObj.field2?1:0}
)
}
}
子类扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
obj:props.obj
}
}
更新=(其中)=>{
this.props.onUpdate(which,!this.state.obj[which]);
this.setState(prevState=>({
obj:{
…prevState.obj,
[which]:!prevState.obj[which],
},
}));
};
render(){
返回(
小孩
子状态中的值:{this.State.obj.field1?1:0}:{this.State.obj.field2?1:0}
{this.update('field1')}>field1
{this.update('field2')}>field2
)
}
}
render(,document.getElementById('root'));
当所有子组件值都可以直接从道具派生时,您不需要在子组件中创建道具副本的状态并对其进行维护,您需要做的是直接修改父组件的状态,就像
import React from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
filedStr: 'some text',
fieldObj: {
field1: true,
field2: true
}
}
}
updObj = (which, val) => {
this.setState(prevState => ({
fieldObj: {
...prevState.fieldObj,
[which]: val,
},
}));
};
render() {
return (
<div>
<h2>Parent</h2>
Value in Parent Component State: {this.state.fieldObj.field1 ? 1 : 0} : {this.state.fieldObj.field2 ? 1 : 0}
<br />
<Child obj={this.state.fieldObj} onUpdate={this.updObj} />
<br />
<Child obj={this.state.fieldObj} onUpdate={this.updObj} />
<br />
<Child obj={this.state.fieldObj} onUpdate={this.updObj} />
</div>
)
}
}
class Child extends React.Component {
constructor(props) {
super(props);
this.state = {
obj: props.obj
}
}
update = (which) => {
this.props.onUpdate(which, !this.props.obj[which]);
};
render() {
return (
<div>
<h4>Child</h4>
Value in Child State: {this.props.obj.field1 ? 1 : 0} : {this.props.obj.field2 ? 1 : 0}<br />
<button type="button" onClick={(e) => { this.update('field1') }}>field1</button>
<button type="button" onClick={(e) => { this.update('field2') }}>field2</button>
</div>
)
}
}
render(<Parent />, document.getElementById('root'));
从“React”导入React;
从'react dom'导入{render};
从“./Hello”导入Hello;
类父类扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
filedStr:“一些文本”,
fieldObj:{
字段1:是的,
字段2:正确
}
}
}
updObj=(其中,val)=>{
this.setState(prevState=>({
fieldObj:{
…prevState.fieldObj,
[哪个]:瓦尔,
},
}));
};
render(){
返回(
父母亲
父组件状态中的值:{this.State.fieldObj.field1?1:0}:{this.State.fieldObj.field2?1:0}
)
}
}
子类扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
obj:props.obj
}
}
更新=(其中)=>{
this.props.onUpdate(which,!this.props.obj[which]);
};
render(){
返回(
小孩
子状态中的值:{this.props.obj.field1?1:0}:{this.props.obj.field2?1:0}
{this.update('field1')}>field1
{this.update('field2')}>field2
)
}
}
render(,document.getElementById('root'));
但是,如果您想知道为什么您的处理方式没有按预期工作,那是因为您没有根据父组件中的状态更新更新子组件的状态,您只在构造函数中设置了一次,而在组件装载时只调用了一次,您需要的是实现
组件willreceiveprops
生命周期功能在这里,我更新了您的代码以满足您的需要-
您对子对象重新渲染的假设是错误的。当子级重新引发构造函数方法时,也就是说,构造函数只被调用一次。要使用下一个道具并更改状态,您需要使用渲染和组件WillReceiveProps。请参见react组件生命周期
问题是当您使用onClick={(e)=>{this.update('field1')}}
和onClick={(e)=>{this.update('field1')}}
您更新了父级的状态,此状态再次传递给子级。但是在孩子身上,你没有使用这种新道具。您使用的是状态,该状态仅在构造函数中更新,而在收到新道具后不会更新。(因为构造函数只被调用一次)
处理新道具的一种方法是直接在渲染中使用道具,因为组件将重新渲染,并且更新的道具将对其可用
另一种方法是,如果您希望使用状态,则更新componentWillReceiveProps中的状态。(我还想指出,强烈建议不要在componentWillReceiveProps和componentDidMount中执行setState)。所以最好使用第一步
componentWillReceiveProps(newProps) {
if(newProps !== this.props){
this.setState({newStateObjects})
}
}
componentWillReceiveProps(newProps) {
if(newProps !== this.props){
this.setState({newStateObjects})
}
}