简体   繁体   English

反应:当父状态是从作为父级属性的外部类中获取和修改时,将父状态传递给子级

[英]React: passing parent state to child when the parent state is sourced and modified from external classes acting as a property in the parent

I'm not sure how to exactly word it out on the title, since the problem is way too specific in my scenario, but anyway basically I have two external classes similar to below: 我不确定如何在标题上准确地写出来,因为问题在我的场景中太具体了,但是无论如何基本上我有两个类似于下面的外部类:

class Config {
    public level: number = 1; //this is a sample state I want to pass

    //sets level
    public setLevel(level: number){
        this.level = level;
    }
}

//wrapper class that uses Config class as a property
class Manager {
    public config: Config = new Config();

    //invokes Config.setLevel() here, but wrapped
    public nextLevel(level: number){
        this.config.setLevel(level)
    }
}

And then my react components are: 然后我的反应成分是:

//here is my parent component using Manager
class ParentComp extends React.Component<any, any>{
    public mngr: Manager = new Manager(); //uses Manager as a property

    constructor(props: any){
        super(props);

        this.state = { config: this.mngr.config }; //adds the Manager instance's property as a state
    }

    public render(){
        //passes the state to a child component
        return(
            <div> <ChildComp level={this.state.config.level}/> </div>
        )
    }

    //this is where I simulate changing the level property using the external class(es)
   componentDidMount(){
        setTimeout(()=>{
           this.mngr.nextLevel(2); //invoke external class method that changes the source object
           console.log('1 sec has passed and a new level has been set.')
        }, 1000)
    }
}

class ChildComp extends React.Component<any, any>{
    constructor(props: any){
        super(props);
        this.state = {level: props.level} //uses the prop to the child's state
    }
}

componentDidMount on ParentComp does change ParentComp.config.level , based on the React dev tools, but not ChildComp.level . componentDidMountParentComp确实改变ParentComp.config.level的基础上,做出反应开发工具,但不ChildComp.level

Why and what to do? 为什么以及该怎么办? I am coming from a Vue background and usually Vue automatically handles these things. 我来自Vue,通常Vue会自动处理这些事情。 I don't understand why it isn't working for React. 我不明白为什么它不适用于React。

您没有在实现中使用setState属性,这就是为什么没有更改的原因。

You never actually call setState() which is a trigger to get the component to re-render, so the Child component would never receive updated props in this scenario. 您永远不会真正调用setState()来触发重新获得组件的触发器,因此在这种情况下,Child组件将永远不会收到更新的道具。 Thus, no changes are reflected. 因此,没有变化反映出来。

You might be able to just trigger a re-render with the updated config value, assuming it is actually updated via this.mgr.nextLevel(2) 假设它实际上是通过this.mgr.nextLevel(2)更新的,您也许可以使用更新后的配置值触发重新渲染。

public componentDidMount(){
    setTimeout(()=>{
       this.mngr.nextLevel(2); //invoke external class method that changes the source object
       this.setState({
          config: this.state.config
       })
    }, 1000)
}

In reference from comments, you can also trigger a state-update in the child-component to reflect these changes. 从注释中引用,您还可以在子组件中触发状态更新以反映这些更改。

In ChildComp.js write the following: ChildComp.js中编写以下内容:

public componentDidUpdate(prevProps){
   if(prevProps.level !== this.props.level){
      this.setState({
         level: this.props.level
      })
   }
}

Do I really have to keep explicitly calling setState() every time I want a React component to react to object changes? 每当我想让React组件对对象更改做出反应时,我真的必须保持显式调用setState()吗? Doesn't it automatically bind stuff on the constructor when I did this.state = {config: this.mngr.config} ? 当我执行this.state = {config: this.mngr.config}时,它不会自动在构造函数上绑定东西吗?

Yes, you do have to call setState() every time you want the component to reflect some UI change. 是的,您每次需要组件反映一些UI更改时都必须调用setState() Doesn't matter if the change is done implicitly or not, the component will not display those changes unless you call the aforementioned method. 不管是否隐式完成更改都无关紧要,除非您调用上述方法,否则组件不会显示这些更改。

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

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