reactjs 在子组件内部,如何找出父组件是什么?

xu3bshqb  于 2023-01-04  发布在  React
关注(0)|答案(2)|浏览(223)

在子组件内部,我尝试找出父组件是什么。用例:我希望根据父组件的不同,对组件应用不同的CSS类。
我读到了Forwarding Refs(我使用函数组件),并认为这可能是解决方案,但我很难应用它。
我的组件如下所示:

export let ParentA = ({ children }) => {
  return <ul data-parent-a>{children}</ul>;
};

export let ParentB = ({ children }) => {
  return <ul data-parent-b>{children}</ul>;
};

export let Child = ({ children }) => {
  return <li data-child>{children}</li>;
};

它们的用法如下:

<ParentA>
  <Child>Item 1</Child>
  <Child>Item 2</Child>
  <Child>Item 3</Child>
</ParentA>

<ParentB>
  <Child>Item 4</Child>
  <Child>Item 5</Child>
  <Child>Item 6</Child>
</ParentB>

由于我只渲染children,因此似乎没有办法传递ref。因此,我尝试创建“private”组件,以便能够像这样传递ref:

export let ParentA = React.forwardRef(({ children }, ref) => {
  return (
    <ul ref={ref} data-parent-a>
      {children}
    </ul>
  );
});

export let ParentB = React.forwardRef(({ children }, ref) => {
  return (
    <ul ref={ref} data-parent-b>
      {children}
    </ul>
  );
});

export let Child = ({ children }) => {
  const Internal = () => {
    return <li data-child>{children}</li>;
  };
  const ref = React.createRef();
  console.log(ref); // logs {current: null}
  return <Internal ref={ref} />;
};

不幸的是,它没有给予任何有用的信息,因为它记录nullhttps://codesandbox.io/s/bold-wing-3r08ii?file=/src/App.js:28-395
我需要做些什么来确定子组件中的父组件是什么?

46qrfjad

46qrfjad1#

组件不应该知道它们的父类。要么显式传递你需要传递的类,要么最好只依赖于CSS:

function ParentA() {
  return (
    <div className="parent-a">
      <Child/>
    </div>
  );
}

function ParentB() {
  return (
    <div className="parent-b">
      <Child/>
    </div>
  );
}

function Child() {
  return (
    <div className="child">
      ...
    </div>
  );
}
.parent-a .child {
  // case parent a styles here
}
.parent-b .child {
  // case parent b styles here
}
iqih9akk

iqih9akk2#

实际上,你并不需要,父组件需要通过在props中传递信息来主动地告诉子组件这个信息。
最基本的方法就是自己动手:

<ParentA>
   <Child isParentA />
   <Child isParentA />
</ParentA>

但是你可以通过让父类自动向所有子类注入一个prop来实现这一点,因为你只是在传递类,所以你可以操纵它,这样你想要的类就被传递了。

export let ParentA = ({ children }) => {
  return (
    <ul data-parent-a>
      {React.Children.map(children, child => (
          React.cloneElement(child, { className: 'child-of-a'})
      ))}
    </ul>
  );
});

现在,如果在ParentA中使用,则child的props中的className将为child-of-a
但是,您应该知道CSS已经允许您根据父对象本地定位子对象:

ul[data-parent-a] li[data-child] {
   // Your styles for children in A 
}

ul[data-parent-b] li[data-child] {
   // Your styles for children in b 
}

相关问题