子组件看不到父组件状态更新

时间:2018-07-18 12:39:50

标签: reactjs react-component react-state-management

我是React的新手,并且面临与状态更新相关的问题。

我有一个父组件。在“父组件”构造函数中,我创建了“子组件”的多个实例。

使用父组件的状态,我将显示子组件实例之一。

子组件实例的一些父组件状态值作为道具传递。

“父组件”状态看起来像这样(我已经简化了代码,因此可以更清楚了)

displayedContainer: {...} // An Instance of Child Component
isLoading: false

Parent Component构造器如下

constructor(props) {
    super(props);
    // Create state
    this.state = {
        isLoading: false,
        displayedContainer: null
    };
    // Create all Child Component (Container)
    this.defaultComponent = <Container 
        isLoading={this.state.isLoading}
    ></Container>
    // Others Child Component are created the same way as above.
    // To clearify the code i have removed them.
}

这是渲染方法

render() { 
    return (
        <div>
            {this.state.displayedContainer}
            <div className="container-left-bar"></div>
        </div>
    )
}

从那里,我可以从一个子组件显示切换到另一个,以便state.displayedContainer工作。但是,state.isLoading更新时,子组件不会检测到它。我认为这是因为我正在构造函数中创建子组件。

如果我想在呈现子组件之前保持创建子组件的逻辑,但是要解决未检测到状态更新的问题,该怎么办?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

问题在于您只能在构造函数中渲染一次<Container />。渲染的实例在内存(this.defaultComponent中),因此,当您调用this.setState时,子代永远不会更新-不会收到有关任何道具更改的通知。此代码应转到render()方法。

这样想: 当React确定this.setState时(例如,您想显示其他容器,然后显示当前容器),React调用render()方法,并应使用更新后的道具重新渲染<Container .../>。但是由于呈现组件的代码不在render()方法中-告诉<Container .../>使用状态中最新的isLoading道具的代码,<Container />从未真正更新过具有isLoading道具(或其他任何道具)的新值。

您应该实现以下目标:

    render() {
        ...
        let renderCurrentContainer = null
        if (...) {
            renderCurrentContainer = <Container isLoading={this.state.isLoading} ...otherPropsHere... />
        }
        else if (...) {
            renderCurrentContainer = ...
        }
        else if (...) {
            renderCurrentContainer = ...
        }
        return <...>
            {renderCurrentContainer}
        </...>
    }

如果您要询问在if条件中放入什么,则需要以某种方式标记当前要呈现的组件,我将留给您创造力,但是您可以使用类似currentRenderedContainerIndex的名称枚举中的值{0, 1, 2}currentRenderedContainer字符串,例如{'FIRST_COMPONENT', 'SECOND_COMPONENT', 'THIRD_COMPONENT'}

然后您将使用以下内容:

if (currentRenderedContainer === 'FIRST_COMPONENT') {
    renderCurrentContainer = <Container isLoading= {this.state.isLoading} ...otherPropsHere... />
}
else if (currentRenderedContainer === 'SECOND_COMPONENT') {
    renderCurrentContainer = ...
}
else if (currentRenderedContainer === 'THIRD_COMPONENT') {
    renderCurrentContainer = ...
}