Reactjs 反应-装饰孩子和处理钥匙

Reactjs 反应-装饰孩子和处理钥匙,reactjs,Reactjs,我正在写一个小组件来装饰一些孩子。鉴于以下示例: constchild=props=>{props.name}; const Parent=props=>{ 让wrappedChildren=React.Children.map(props.Children,c=>{ 返回( {c} ); }); 返回( {wrappedChildren} ); } const Consumer=props=>{ 让子项=[0,1,2]。映射(num=>{ 返回; }); 返回{children}; });J

我正在写一个小组件来装饰一些孩子。鉴于以下示例:

constchild=props=>{props.name};
const Parent=props=>{
让wrappedChildren=React.Children.map(props.Children,c=>{
返回(
{c}
);
});
返回(
{wrappedChildren}
);
}
const Consumer=props=>{
让子项=[0,1,2]。映射(num=>{
返回;
});
返回{children};
});
Javascript
Array.map(fn)
实际上将3个参数传递给
fn
秒作为索引。因此,您需要做的是:
let wrappedChildren=props.children.map((c,i)=>{c})

将与当前版本的React 15.6.1(可能还与以前的版本一起使用)一起使用。然而,有一个稍微好一点的方法可以通过一个小的调整来实现你的目标,那就是在一个道具上授权提升,而不是直接使用

原因是键的概念是在创建组件之前由React内部控制的,因此它属于实现细节类别,其结果是React的未来版本可能会在您没有注意到的情况下破坏您的代码

相反,您可以在
子组件
上使用一个道具,例如
id
,前提是假设每个子组件都有某种唯一的值。您的代码将导致:

const Child = props => <div>{props.name}</div>;

const Parent = props => {
  return React.Children.map(props.children, c => {
     return (<Decorator key={c.props.id}>
       {c}
     </Decorator>);
  });

  return (<div>
    {wrappedChildren}
  </div>);
}

const Consumer = props => {
     let children = [0, 1, 2].map(num => {
       return <Child id={num} name={num} />;
     });
    return <Parent>{children}</Parent>;
});
  • 在父级渲染中,按以下方式将每个关键点指定给装饰器组件

     render() {
       return React.Children.map(props.children, (c, i) => {
         return (<Decorator key={this.uuids[i]}>
           {c}
         </Decorator>);
       });
     }
    
    render(){
    返回React.Children.map(props.Children,(c,i)=>{
    返回(
    {c}
    );
    });
    }
    
  • 一些有用的链接:


    我认为你的方法很好。你确实需要顶层的钥匙。使用孩子的钥匙(如果有)。如果没有,请退回到
    索引
    ,如React建议的那样:

    当渲染项没有稳定的ID时,可以使用项索引作为键作为最后手段

    请注意:

    如果项目可以重新排序,我们不建议对键使用索引,因为那样会很慢

    资料来源:

    constchild=props=>{props.name};
    const Parent=props=>{
    让wrappedChildren=React.Children.map(props.Children,(c,i)=>{
    const key=c.key?`key-${c.key}`:`index-${i}`
    返回(
    {c}
    );
    });
    返回(
    {wrappedChildren}
    );
    };
    const Consumer=()=>{
    让子项=[0,1,2]。映射(num=>{
    返回;
    });
    返回{children};
    };
    
    我绝对不想使用索引作为键。如果孩子有钥匙,他更愿意这样做。在这种情况下,使用索引意味着数组重新排序时出现问题。我检查了文档,您没有使用Array.map(),这是子数据结构上的map函数使用
    React.children.toArray
    map
    如何?如果您的数组被重新排列,您会看到什么问题?根据文档:如果项目可以重新排序,我们不建议对键使用索引,因为那样会很慢。如果你感兴趣的话,你可以阅读一篇关于为什么键是必要的深入解释。这确实有效,但我的例子可能有点小。假设一个网格组件接受任何类型的子组件,它可能是一个div,也可能是一个按钮,或者是一些自定义组件。我必须为每个道具类型添加一个id道具顺便说一句,我完全同意密钥是一个内部impl细节。:)我添加了一个建议,用于跳过在孩子中显式传递道具。如果您预先生成了一个UUID数组,然后在react中使用
    上下文
    api根据需要访问此列表,会怎么样?我认为您的方法很好。作为网格组件的用户,如果在数组中创建多个子元素,则很可能要为它们设置关键帧。如果直接添加这些子项(正如您所说,可能是按钮、div等),那么它们可能没有键。知道有些孩子可能有钥匙,也可能没有,装饰者应该检查钥匙是否存在,并分别添加钥匙或不带钥匙继续。这样,decorator不会给子级重新渲染过程带来任何新的内容,网格用户将完全控制它。
    
     render() {
       return React.Children.map(props.children, (c, i) => {
         return (<Decorator key={this.uuids[i]}>
           {c}
         </Decorator>);
       });
     }
    
    const Child = props => <div>{props.name}</div>;
    const Parent = props => {
      let wrappedChildren = React.Children.map(props.children, (c, i) => {
        const key = c.key ? `key-${c.key}` : `index-${i}`
        return (
          <Decorator key={key}>
            {c}
          </Decorator>
        );
      });
    
      return (
        <div>
          {wrappedChildren}
        </div>
      );
    };
    const Consumer = () => {
      let children = [ 0, 1, 2 ].map(num => {
        return <Child key={num} name={num} />;
      });
      return <Parent>{children}</Parent>;
    };