将道具传递给 React 中的特定嵌套子项

我正在尝试为孩子们配置一些道具。


在这个虚拟示例中,我正在测试该函数,以便使用以下属性专门针对任何嵌套或未嵌套的子对象:swipeMe。


div如果在 my on the里面render function它只包含一个孩子,它工作得很好,就像这样:


    <SwapableItems>

      <div>

        {/*the p element will get the red color as defined on childrenHandler*/}

        <p swipeMe>Add Props</p> 

      </div>

    </SwapableItems>

然而,如果我在我的中添加更多的孩子div,不知何故我猜我的三元操作childrenHandler效果不佳,我不知道为什么......

  • 如果它有孩子,克隆这个元素并调用childrenHandler传递它的孩子。

  • 如果它有我想要的道具,克隆元素并用它做点什么。

  • 如果以上都不是,则只需克隆该元素。

return childHasChildren
      ? React.cloneElement(child, {}, childHasChildren)
      : child.props.swipeMe
      ? React.cloneElement(child, { ...swipeMeProps })
      : React.cloneElement(child, {});

下面是完整的脚本。

import React from "react";

import ReactDOM from "react-dom";


function App() {

  return (

    <SwapableItems>

      <div>

        <p swipeMe>Add Props</p>

        <div>Don't Add Props</div>

      </div>

    </SwapableItems>

  );

}


function SwapableItems({ children }) {

  const content = childrenHandler(children, { style: { color: "red" } });

  return content;

}


const childrenHandler = (children, swipeMeProps) => {

  const childEls = React.Children.toArray(children).map((child) => {

    const childHasChildren =

      child.props.children && React.isValidElement(child.props.children)

        ? childrenHandler(child.props.children, swipeMeProps)

        : undefined;

    return childHasChildren

      ? React.cloneElement(child, {}, childHasChildren)

      : child.props.swipeMe

      ? React.cloneElement(child, { ...swipeMeProps })

      : React.cloneElement(child, {});

  });

  return childEls;

};

const rootElement = document.getElementById("root");

ReactDOM.render(<App />, rootElement);


牧羊人nacy
浏览 110回答 3
3回答

小怪兽爱吃肉

我测试了这项工作。如果有孩子,我用 SwapableItems 包裹嵌套的孩子。function SwapableItems({ children }) {  const props = { style: { color: "red" } };  return Children.map(children, (child) => {    let nestedChild = child.props.children;    const hasNestedChild = nestedChild && typeof nestedChild !== "string"    if (hasNestedChild) {      nestedChild = <SwapableItems>{nestedChild}</SwapableItems>;    }    return child.props?.swipeMe || hasNestedChild      ? cloneElement(child, child.props?.swipeMe ? props : {}, [nestedChild])      : child;  });}

呼唤远方

child.props.children是一个数组,所以React.isValidElement(child.props.children)总是虚假的,要修复它,请尝试React.cloneElement在其上使用:React.isValidElement(React.cloneElement(child.props.children)); // true样式重置示例:const styleA = {&nbsp; color: "blue"};const InlineReset = ({ children }) => {&nbsp; return React.Children.map(children, child => {&nbsp; &nbsp; console.log(child.props);&nbsp; &nbsp; return React.cloneElement(child.props.children, { style: null });&nbsp; });};export default function App() {&nbsp; return (&nbsp; &nbsp; <InlineReset>&nbsp; &nbsp; &nbsp; <div>&nbsp; &nbsp; &nbsp; &nbsp; <h1 style={styleA}>Hello </h1>&nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; </InlineReset>&nbsp; );}

九州编程

这是解决方案:我已经初始化了一个variable,它将保存recursion逻辑的外部并且未定义。let childHasChildren;我已经将代码封装在一个if声明中并进行了一些修改:“如果child有孩子,要么是 要么array,object如果在传递的范围内children有/是有效React元素”const deeperChildren = child.props.children;    const arrayOfChildren = Array.isArray(deeperChildren);    const singleChildren =      typeof deeperChildren === "object" && deeperChildren !== null;    if (      (arrayOfChildren &&        deeperChildren.some((c) => React.isValidElement(c))) ||      (singleChildren && React.isValidElement(deeperChildren))    ) {为了不出错地传递递归,以防语句中的代码if被调用,我克隆了一个过滤器/单个对象,其子对象将是 React 有效元素,然后我只将这些/这个传递到递归中:const validChildren = arrayOfChildren        ? deeperChildren.filter((c) => React.isValidElement(c))        : deeperChildren;现在它接受一个有孩子的项目,或者一个数组。这可以配置为动态传递道具,默认道具和其他可以从组件外部传递的道具,尽管后者不是我的情况。为了在不使用这些解决方案的情况下实现更复杂的东西,例如 render props、props contracts、HOCs 等,需要这个解决方案。const childrenHandler = (children, swipeMeProps) => {  const childEls = React.Children.toArray(children).map((child) => {    let childHasChildren;    const deeperChildren = child.props.children;    const arrayOfChildren = Array.isArray(deeperChildren);    const singleChildren =      typeof deeperChildren === "object" && deeperChildren !== null;    if (      (arrayOfChildren &&        deeperChildren.some((c) => React.isValidElement(c))) ||      (singleChildren && React.isValidElement(deeperChildren))    ) {      const validChildren = arrayOfChildren        ? deeperChildren.filter((c) => React.isValidElement(c))        : deeperChildren;      childHasChildren = childrenHandler(validChildren, swipeMeProps);    }    return childHasChildren      ? React.cloneElement(child, {}, childHasChildren)      : child.props.swipeMe      ? React.cloneElement(child, { ...swipeMeProps })      : React.cloneElement(child, {});  });  return childEls;};
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript