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

时间:2019-09-09 05:50:57

标签: javascript reactjs typescript

我不确定如何在标题上准确地写出来,因为问题在我的情况中太具体了,但是无论如何,基本上我有两个类似于下面的外部类:

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)
    }
}

然后我的反应组件是:

//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
    }
}
基于React开发工具,componentDidMount上的

ParentComp确实改变了ParentComp.config.level,但没有改变ChildComp.level

为什么以及该怎么办?我来自Vue,通常Vue会自动处理这些事情。我不明白为什么它不适用于React。

2 个答案:

答案 0 :(得分:2)

您没有在实现中使用res.set({x-token: generated_token}); // In your code get // get token from response localStorage.setItem('token', token); // now whenever calling api pass token as header 属性,这就是为什么没有变化的原因。

答案 1 :(得分:1)

您从不实际调用setState(),这是使组件重新呈现的触发器,因此,在这种情况下,Child组件将永远不会收到更新的道具。因此,没有任何变化反映出来。

假设实际上通过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)
}

从注释中引用,您还可以在子组件中触发状态更新以反映这些更改。

ChildComp.js 中编写以下内容:

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

我真的必须继续明确地打电话吗   每当我想让React组件对对象做出反应时,setState()   变化?我不是自动绑定构造函数上的东西吗   是this.state = {config: this.mngr.config}吗?

是的,每次您希望组件反映一些UI更改时,都必须调用setState()。不管是否隐式完成更改都无关紧要,除非您调用上述方法,否则组件不会显示这些更改。