我正在寻找一种方法来访问其父组件中每个子组件的位置
我有一个名为
Slider
的组件,它可以有多个子组件。我们称它们为 SliderSection
,每个 SliderSection
可以有多个 SliderStep
组件。
它看起来像这样:
<Slider>
<SliderSection>
<SliderStep>step 1</SliderStep>
<SliderStep>step 2</SliderStep>
<SliderStep>step 3</SliderStep>
</SliderSection>
<SliderSection>
<SliderStep>step 1</SliderStep>
</SliderSection>
<SliderSection>
<SliderStep>step 1</SliderStep>
<SliderStep>step 2</SliderStep>
</SliderSection>
</Slider>
SliderSection
和SliderStep
内部都有一个功能,它依赖于它们在父组件中的位置(Slider
)
我曾经将它们的位置编号作为支柱传递给每个组件,如下所示:
使用名为
sectionNum
和 stepNum
的道具
<Slider>
<SliderSection sectionNum={1}>
<SliderStep stepNum={1}></SliderStep>
<SliderStep stepNum={2}></SliderStep>
<SliderStep stepNum={3}></SliderStep>
</SliderSection>
<SliderSection sectionNum={2}>
<SliderStep stepNum={1}></SliderStep>
</SliderSection>
<SliderSection sectionNum={3}>
<SliderStep stepNum={1}></SliderStep>
<SliderStep stepNum={2}></SliderStep>
</SliderSection>
</Slider>
注意
sectionNum
如何从 1 开始并针对每个 SliderSection
上升,sliderNum
也从 1 开始并针对每个 SliderStep
inside SliderSection
上升,并且当 SliderSection
更改时重置为 1并上升。(基本上每个部分的第一步
stepNum
是1)
但这除了不是自动的之外还有一些后果。
如何在不手动传递道具的情况下访问位置?
我希望能够根据某些值返回 null(例如,如果 x 为 true,则不渲染步骤 2),但由于
sectionNum
和 stepNum
属性是 硬编码 它会搞乱索引滑块,所以我需要一种方法来处理这个问题,即使例如 section#1-step#2 未在国际范围内呈现 section#1-step#3 应更改为 section#1-step#2
您无法直接从组件访问父级,但您可以让父级使用
React.Children.map
和 React.cloneElement
在渲染每个子级之前将索引属性注入到每个子级中。
import React from "react";
function Slider({ children }) {
const childrenWithProps = React.Children.map(children, (child, index) =>
React.cloneElement(child, { index }),
);
return <div>{childrenWithProps}</div>;
}
function SliderSection({ children, index }) {
const childrenWithProps = React.Children.map(children, (child, index) =>
React.cloneElement(child, { index }),
);
return (
<div>
Section {index}
<br />
{childrenWithProps}
</div>
);
}
function SliderStep({ children, index }) {
return (
<div>
Step {index}: {children}
</div>
);
}
export default function App() {
return (
<Slider>
<SliderSection>
<SliderStep>step 1</SliderStep>
<SliderStep>step 2</SliderStep>
<SliderStep>step 3</SliderStep>
</SliderSection>
<SliderSection>
<SliderStep>step 1</SliderStep>
</SliderSection>
<SliderSection>
<SliderStep>step 1</SliderStep>
<SliderStep>step 2</SliderStep>
</SliderSection>
</Slider>
);
}
渲染
Section 0
Step 0: step 1
Step 1: step 2
Step 2: step 3
Section 1
Step 0: step 1
Section 2
Step 0: step 1
Step 1: step 2