更新,立即解决:
我将scopes
移至state
,现在scopes
数据是最新的。
我正在使用带有新上下文API的渲染道具。为了简化起见,可以说API有两种方法。 ChildComponent通过上下文API使用方法A,methodB
用作渲染道具。
问题是我需要按以下顺序进行初始化:
ChildComponent
从上下文API运行methodA
Component
属性:已填充this.scopes
当methodB
运行(通过渲染道具)时,它知道this.scope
目前,methodB
在this.scope
填充this.scope = {}
之前运行methodA
我尝试过setTimeout
,但我认为这不是最好的主意...
class Component extends React.Component{
scopes = {};
render(){
const api = {
methodA: (name, fields) => {
this.scopes[name] = fields;
},
methodB: (name) => {
console.log(this.scopes[name])
}
}
return (
<ComponentContext.Provider value={{ api }}>
{typeof children === 'function' ? children(api) : children}
</ComponentContext.Provider>
);
}
}
/************* CHILD COMPONENT */
class ChildComponent extends React.Component{
static contextType = ComponentContext;
componentWillMount() {
const { api } = this.context;
api.methodA(name, this.fields);
}
render() {
const { children } = this.props;
return children;
}
}
/************* COMPONENTS IMPELENTATION WITH THE PROBLEM */
<Component>
{(api) => (
<ChildComponent name="foo"> // it should at first add foo to the Component this.scope;
<div>Some Child 1</div>
</ChildComponent>
<ChildComponent name="bar"> // it should at first add bar to the Component this.scope;
<div>Some Child 2</div>
</ChildComponent>
{api.methodB(foo)} // not working because for now this.scopes is empty object (should be: {foo: someFields, bar: someFields})
)}
</Component>
我希望得到this.scope = {foo: ...someFields, bar: ...someFields }
的结果,在初次运行后暂时this.scope= {}
,对methodB
的下一次调用很好,并且(this.scope = {foo: ...someFields, bar: ...someFields}
。
谢谢您的提示。
答案 0 :(得分:0)
您可以在同一生命周期中添加和使用范围,因此可以使用传递的上下文的旧版本。您可以将api.methodB(foo)
从Render()
方法移至componentDidUpdate()
步骤,以确保执行时具有新的上下文。
答案 1 :(得分:0)
如果初始化仅发生一次且同步发生,则父Component
在挂载时可视为已初始化。
如果methodB
的目的是返回用于初始化父对象的数据,则应在初始化时更新父对象的状态。在this.state
外部存储组件状态是一种反模式。可能有一个标志明确表明初始化已完成:
class Component extends React.Component{
state = {
scopes: {},
init: false,
methodA: (name, fields) => {
if (this.state.init) return;
this.state.scopes[name] = fields;
},
methodB: (name) => this.state.init ? this.scopes[name] : null
};
componentDidMount() {
this.setState({ init: true });
}
render(){
return (
<ComponentContext.Provider value={this.state}>
...
</ComponentContext.Provider>
);
}
}
除非初始化完成,否则api.methodB(foo)
将返回null
。