【问题标题】:react keeping state of render props wrapped components反应保持渲染道具包装组件的状态
【发布时间】:2019-04-21 08:15:06
【问题描述】:

我通过 children 属性作为函数创建了以下渲染道具组件:

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 为假,它实际上只是渲染包装的组件,或者如果道具为真,则添加一层加载。 它“非常完美”地工作。

我确实从另一个组件以这种方式调用它:

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 属性时,包装组件不会保留状态,所以如果我更改内部文本字段的值,添加加载层时,以及删除它时,该值不被采用,因此输入字段仍然使用初始值呈现。

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

【问题讨论】:

  • 我说的不是应用程序状态,而是简单的组件状态。我不想为此使用 redux。我只需要一种方法来存储传入的包装组件的当前状态(this.state 让我们说理解)。

标签: javascript reactjs


【解决方案1】:

您的组件状态正在重置,因为当您的加载状态发生变化时,React 正在创建一个全新的组件。如果将console.log 添加到HomeTestForm 的构造函数中,您可以看到这些。 React 认为这是必要的,因为 GenericAbstractLoader 中的三元运算符。如果您可以将GenericAbstractLoader 中的render 函数重构为类似于以下示例的内容,则可以为 React 提供它需要的上下文,以便在各个渲染中保持组件实例。

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

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

另外,与您的问题无关,根据您当前的示例,您不需要使用渲染道具。 GenericAbstractLoader 中的 render 函数可以在没有函数调用的情况下渲染 {this.props.children},您可以将道具直接放在子组件上,如下例所示。您可能刚刚为 SO 简化了示例,并且遇到需要渲染道具的情况,但我想指出这一点以防万一。

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

【讨论】:

    猜你喜欢
    • 2018-12-03
    • 1970-01-01
    • 2019-07-26
    • 1970-01-01
    • 2022-01-02
    • 2022-01-22
    • 2021-10-31
    • 2020-10-07
    • 1970-01-01
    相关资源
    最近更新 更多