反应保持渲染道具包裹组件的状态

时间:2018-11-18 23:58:39

标签: javascript reactjs

我通过children prop作为函数创建了以下渲染props组件:

export class GenericAbstractLoader extends React.Component<IGenericAbstractLoaderRenderProps, any> {
    constructor(props: IGenericAbstractLoaderRenderProps) {
        super(props);
    }

    public render() {
        return this.props.isLoading ? (
            <div className="generic-abstract-loader-wrapper">
                <div className="generic-abstract-loader">
                    <img src={loader} />
                </div>
                {this.props.children(this.props)}
            </div>
        ) : (
            this.props.children(this.props)
        );
    }
}

如果isLoading为假,它实际上仅呈现包装的组件,如果prop为true,则添加一个加载层。 它的工作原理“非常完美”。

我确实从其他组件中以这种方式调用它:

public render() {
    return (
        <div>
            <button onClick={this.justDisable}>JUST SET FALSE TO STATE</button>
            <br />
            <button onClick={this.enableDisable}>Disable/Enable Elements</button>
            <br />

            <GenericAbstractLoader customProp="custom prop" isLoading={this.state.shouldDisable}>
                {props => <HomeTestForm {...props} />}
            </GenericAbstractLoader>
        </div>
    );
}

如您所见,包装的组件是一个简单的HomeTestForm,其中仅包含一个输入文本:

export class HomeTestForm extends React.Component<IGenericAbstractLoaderHOCProps, any> {
    constructor(props: IGenericAbstractLoaderHOCProps) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
        this.state = { value: 'Initial Value' };
    }

    public render() {
        return (
            <div>
                    <input type="text" value={this.state.value} onChange={this.handleChange} />
            </div>
        );
    }

    public handleChange(event: any) {
        this.setState({ value: event.target.value });
    }
}

我的问题是,当我切换isLoading道具时,状态不会由包装的组件保持,因此如果更改内部文本字段的值,添加加载层以及移除时它不使用值,因此输入字段仍使用init值呈现。

使用渲染道具创建持久包装组件的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

您的组件状态将被重置,因为当您的加载状态更改时,React会创建一个全新的组件。如果将import sys print(sys.version) 添加到console.log的构造函数中,则可以看到这些内容。由于HomeTestForm中的三元运算符,React认为这是必要的。如果您可以将GenericAbstractLoader中的render函数重组为类似于以下示例的内容,则可以为React提供它需要的上下文,以在整个渲染过程中持久保留组件实例。

GenericAbstractLoader

React的文档在Reconciliation下有一个简短的章节。这种情况属于“不同类型的元素”标题下。

而且,与您的问题无关,根据当前示例,您无需使用渲染道具。 render() return ( <div className={this.props.isLoading ? "generic-abstract-loader-wrapper" : ""}> {this.props.isLoading && <img src={loader} />} {this.props.children(this.props)} </div> ); } 中的render函数可以仅渲染GenericAbstractLoader而无需调用该函数,您可以将道具直接放在子组件上,如下例所示。您可能只是简化了SO的示例,并遇到了需要渲染道具的情况,但是我想指出这一点,以防万一。

{this.props.children}