为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

牧羊人nacy 2023-06-09 15:06:54
我正在尝试为孩子们配置一些道具。在这个虚拟示例中,我正在测试该函数,以便使用以下属性专门针对任何嵌套或未嵌套的子对象: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);
查看完整描述

3 回答

?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

我测试了这项工作。如果有孩子,我用 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;

  });

}


查看完整回答
反对 回复 2023-06-09
?
呼唤远方

TA贡献1856条经验 获得超11个赞

child.props.children是一个数组,所以React.isValidElement(child.props.children)总是虚假的,要修复它,请尝试React.cloneElement在其上使用:


React.isValidElement(React.cloneElement(child.props.children)); // true

样式重置示例:


const styleA = {

  color: "blue"

};


const InlineReset = ({ children }) => {

  return React.Children.map(children, child => {

    console.log(child.props);


    return React.cloneElement(child.props.children, { style: null });

  });

};


export default function App() {

  return (

    <InlineReset>

      <div>

        <h1 style={styleA}>Hello </h1>

      </div>

    </InlineReset>

  );

}


查看完整回答
反对 回复 2023-06-09
?
九州编程

TA贡献1785条经验 获得超4个赞

这是解决方案:


我已经初始化了一个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;

};


查看完整回答
反对 回复 2023-06-09
  • 3 回答
  • 0 关注
  • 106 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信