繁体   English   中英

反应-从孩子身上移除道具

[英]React - Remove prop from child

我需要从孩子身上移除道具。

我有一个容器元素,该元素使用子元素上的属性对子元素进行一些增强。 在渲染之前,应从子级中删除该属性。

<AsyncContainer>
   <Button onClick={this.asyncStuff} asyncHandler="onClick"/>
</AsyncContainer>

呈现之前,应从按钮中删除asyncHandler属性。

AsyncContainer使用React.cloneElement(child, properties)

我尝试将asyncHandler属性设置为空,将其设置为undefined,然后从child.props中删除该属性。 似乎不可能再次摆脱此属性。

我刚遇到这个问题。 您可以只创建一个新元素,并使用旧元素的类型和要传递的道具。 我不确定这是否是反模式,我偶然发现了它,到目前为止它似乎运行良好。

它看起来应该像这样:

function AsyncContainer(props) {
  const child = React.Children.only(props.children)
  const { asyncHandler, ...childProps } = child.props
  // do asyncHandler stuff
  return React.createElement(child.type, childProps)
}

根据评论,您不能直接修改道具,因为它们是不可变的。

但是,我认为我对此问题有一个简单的解决方案。 我不知道它是什么库或它是如何工作的,所以这可能会或可能不会 但是,这是在安装组件之前如何移除支撑的一般答案。

话虽如此,我会尝试创建自己的呈现<Button />的组件:

class MyButtonComponent extends React.Component {

...

  render() {
    return <Button onClick={this.props.onClickHandler} />;
  }
}

然后在组件中进行增强:

render() {
  <AsyncContainer>
    <MyButtonComponent onClickHandler={this.asyncStuff} asyncHandler="onClick"/>
  </AsyncContainer>
}

这样,您可以在<Button />组件上维护onClick asyncHandler但不会传递非法的asyncHandler


编辑:

或者,您也可以执行以下操作:

class MyButtonComponent extends React.Component {

...

  componentWillMount() {
    let newProps = this.props;
    delete newProps.asyncHandler;
    this.setState({properties: newProps}):
  }

  render() {
    return <Button {...this.state.properties} />;
  }
}

这会将所有道具(使用spread操作符 )应用于<Button />asyncHandler除外,我们通过在state下创建props的副本但移除了asyncHandler方式在组件安装之前将其删除。

还要检查我给类似问题的答案

function AsyncContainer(props) {
  const child = React.Children.only(props.children);
  return React.cloneElement(
    child,
    { asyncHandler: undefined }
  );
}

这个怎么运作

  1. 您使用React.cloneElement克隆元素,因为element是不可变的,更改道具的唯一方法是创建克隆。
  2. 使用第二个React.cloneElement参数添加新道具并删除旧道具。 不需要的道具应该分配undefined 您需要执行此操作,因为默认情况下,cloned元素会与其所有props一起被克隆。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM