渲染道具-在某些组件配置后需要执行功能

时间:2019-01-14 13:00:47

标签: reactjs

更新,立即解决:

我将scopes移至state,现在scopes数据是最新的。


我正在使用带有新上下文API的渲染道具。为了简化起见,可以说API有两种方法。 ChildComponent通过上下文API使用方法A,methodB用作渲染道具。

问题是我需要按以下顺序进行初始化:

  1. ChildComponent从上下文API运行methodA

  2. Component属性:已填充this.scopes

  3. methodB运行(通过渲染道具)时,它知道this.scope

目前,methodBthis.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}

谢谢您的提示。

2 个答案:

答案 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