Javascript 反应-从儿童身上取下道具

Javascript 反应-从儿童身上取下道具,javascript,reactjs,Javascript,Reactjs,我需要从一个孩子身上取下一个道具 我有一个容器元素,它使用它的子元素上的一个属性对子元素执行一些增强。在呈现之前,应该从子对象中删除该属性 <AsyncContainer> <Button onClick={this.asyncStuff} asyncHandler="onClick"/> </AsyncContainer> 在呈现之前,应从按钮中删除asyncHandler属性 <AsyncContainer> <Butt

我需要从一个孩子身上取下一个道具

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

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

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

<AsyncContainer>
   <Button onClick={this.asyncStuff} asyncHandler="onClick"/>
</AsyncContainer>
AsyncContainer使用
React.cloneElement(子元素、属性)


我尝试过将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)
}
工作原理
  • 您可以使用
    React.cloneElement
    克隆元素,因为元素是不可变的,更改其属性的唯一方法是创建克隆
  • 使用第二个
    React.cloneElement
    参数添加新道具并移除旧道具。不需要的道具应指定为
    未定义的
    。您需要这样做,因为默认情况下克隆的元素是用它的所有道具克隆的

  • React中的
    道具是不可变的,因此组件本身无法更改。父级必须修改
    prop
    ,然后将其传递给组件。您不能在child中使用props,因为它们是只读的:也许您可以克隆子级并以某种方式替换属性对象?这样,prop
    asynchHandler
    将设置为
    未定义的
    ,但是如何从克隆的组件道具中完全移除呢?你真的测试过这个吗?我不认为可以使用这样一个未定义的值来替换函数。我建议查看
    React.createElement()
    这在许多情况下都有效,但有一个缺点。从文档中可以看出:“……它还保留了ref。这意味着,如果您得到一个带有ref的子元素,您不会意外地从您的祖先那里窃取它。您将获得附加到新元素的相同ref。”
    class MyButtonComponent extends React.Component {
    
    ...
    
      componentWillMount() {
        let newProps = this.props;
        delete newProps.asyncHandler;
        this.setState({properties: newProps}):
      }
    
      render() {
        return <Button {...this.state.properties} />;
      }
    }
    
    function AsyncContainer(props) {
      const child = React.Children.only(props.children)
      const { asyncHandler, ...childProps } = child.props
      // do asyncHandler stuff
      return React.createElement(child.type, childProps)
    }
    
    function AsyncContainer(props) {
      const child = React.Children.only(props.children);
      return React.cloneElement(
        child,
        { asyncHandler: undefined }
      );
    }