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

时间:2017-03-27 08:07:56

标签: javascript reactjs

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

我有一个容器元素,它在其子元素上使用属性来对子元素执行一些增强。在呈现之前,应该从子项中删除该属性。

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

在渲染之前,应该从按钮中删除asyncHandler属性。

AsyncContainer使用React.cloneElement(child, properties)

我已经尝试将asyncHandler属性置零,将其设置为undefined并从child.props中删除该属性。似乎不可能再次摆脱这个属性。

3 个答案:

答案 0 :(得分:4)

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

看起来应该是这样的:

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

答案 1 :(得分:0)

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

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

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

class MyButtonComponent extends React.Component {

...

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

然后在组件中进行增强:

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

通过这种方式,您可以在onClick组件上维护<Button /> eventlistener,但不会传递非法的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 operator)应用于<Button />,但asyncHandler除了props之外,我们会在装入组件之前删除state,创建{{1}的副本} asyncHandler,但已移除public static List<ListItem> list = new ArrayList<>();

同时检查this answer我提出了类似的问题。

答案 2 :(得分:0)

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

工作原理

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