我正在尝试在React JS中编写一个容器,我正在使用VisibilitySensor检查何时我的组件在屏幕上可见。一切工作都很好,但是可见性传感器的事件可能很快发生,我需要对每个事件做出反应。我的目标是在屏幕右侧绘制页面内容的索引,并向用户显示实际看到的部分。在一些小页面中,很难处理。
因为如果我使用“ useState”来设置每个部分可见的值(一旦有了可见性计数,我就可以得到该部分可见的比率),该事件将很快结束相对于每个部分的总组件数),事件发生时尚未填充状态,因此我无法获得准确的计数。所以现在我正在使用引用(useRef),因为它们是不可变的,并保留了渲染之间的状态(这使我不必使用在页面重新加载之间不会消失的全局变量)。我的问题是实现我要完成的工作的正确方法是什么,不要认为使用refs是执行此操作的正确方法...即使它工作得很好...
我尝试了更复杂的状态(所有节处于一个状态),更稀疏的状态(每个节一个状态),全局变量(在重载时不死),局部变量(每个渲染都重新初始化),最后,裁判似乎很好用...
该代码尚未公开,而且相当长,但是我认为您可以了解我正在尝试的内容
使用状态时,我会丢失事件,而引用或全局变量则不会发生这种情况。
编辑:
我想要达到的目标是:
const getMaxs = (section1, section2, [ ... ], sectionN) => {
/* Compute ratios for the sections, it is, given the components visible (the parameters) divide it for the total number of components per section and return a list of sections with the maximum ratio of visible components */
return [sectionA, sectionB, [ ... ], sectionN];
}
const MyContainer: React.FC<ContainerProps> = ({ prop1, prop2 ... }) {
const [firstSectionCompsVisible, setFirstSection] = React.useState(0);
const [secondSectionCompsVisible, setSecondSection] = React.useState(0);
[ ... ]
const [NSectionCompsVisible, setNSection] = React.useState(0);
return(
<Layout activeSections={getMaxs(firstSectionCompsVisible, secondSectionCompsVisible, NSectionCompsVisible)}>
<Container>
/* First section */
<Grid container justify="center" id="IdFirst">
<Grid item xs={8}>
<VisibilitySensor
onChange={(visible: boolean) => {
setFirstSection(visible ? firstSectionCompsVisible + 1 : firstSectionCompsVisible - 1)
}}
>
<Component_1_FirstSection />
</VisibilitySensor>
<VisibilitySensor
onChange={(visible: boolean) => {
setFirstSection(visible ? firstSectionCompsVisible + 1 : firstSectionCompsVisible - 1)
}}
>
<Component_2_FirstSection />
</VisibilitySensor>
[ ... ]
<VisibilitySensor
onChange={(visible: boolean) => {
setFirstSection(visible ? firstSectionCompsVisible + 1 : firstSectionCompsVisible - 1)
}}
>
<Component_N_FirstSection />
</VisibilitySensor>
</Grid>
</Grid>
/* Second section */
<Grid container justify="center" id="IdSecond">
<Grid item xs={8}>
<VisibilitySensor
onChange={(visible: boolean) => {
setSecondSection(visible ? secondSectionCompsVisible + 1 : secondSectionCompsVisible -1)
}}
>
<Component_1_SecondSection />
</VisibilitySensor>
<VisibilitySensor
onChange={(visible: boolean) => {
setSecondSection(visible ? secondSectionCompsVisible + 1 : secondSectionCompsVisible -1)
}}
>
<Component_2_SecondSection />
</VisibilitySensor>
[ ... ]
<VisibilitySensor
onChange={(visible: boolean) => {
setSecondSection(visible ? secondSectionCompsVisible + 1 : secondSectionCompsVisible -1)
}}
>
<Component_N_SecondSection />
</VisibilitySensor>
</Grid>
</Grid>
/* Section N here...*/
</Container>
</Layout>
);
}
我尝试了对所有部分都带有对象的大状态,这甚至更糟。如果这样做,我的状态将无法足够快地传播,因此我将永远无法获得不同部分的正确比率,因此我的目录索引不会显示正确的信息。
如果我使用全局变量而不是状态来存储变量的可见性,则全局var的值将在页面重新加载之间保持不变,我不希望这样做,因为在装入组件时,我收到了需要获取的事件页面的初始状态,如果我从useState(() => {reinitialise global vars}, [])
重新初始化了全局变量,则会丢失其中的一些状态,并且局部变量将在每个渲染器上重新初始化,所以我实际上在做的是:>
const getMaxs = (section1, section2, [ ... ], sectionN) => {
/* Compute ratios for the sections, it is, given the components visible (the parameters) divide it for the total number of components per section and return a list of sections with the maximum ratio of visible components */
return [sectionA, sectionB, [ ... ], sectionN];
}
const MyContainer: React.FC<ContainerProps> = ({ prop1, prop2 ... }) {
const firstSectionCompsVisible = React.useRef(0);
const secondSectionCompsVisible = React.useRef(0);
[ ... ]
const NSectionCompsVisible = React.useRef(0);
const [activeSections, setActive] = React.useState([]);
return(
<Layout activeSections={activeSections}>
<Container>
/* First section */
<Grid container justify="center" id="IdFirst">
<Grid item xs={8}>
<VisibilitySensor
onChange={(visible: boolean) => {
firstSectionCompsVisible.current = visible ? firstSectionCompsVisible.current + 1 : firstSectionCompsVisible.current - 1;
setActive(getMaxs(firstSectionCompsVisible.current, secondSectionCompsVisible.current, [ ... ], NSectionCompsVisible.current))
}}
>
<Component_1_FirstSection />
</VisibilitySensor>
<VisibilitySensor
onChange={(visible: boolean) => {
firstSectionCompsVisible.current = visible ? firstSectionCompsVisible.current + 1 : firstSectionCompsVisible.current - 1;
setActive(getMaxs(firstSectionCompsVisible.current, secondSectionCompsVisible.current, [ ... ], NSectionCompsVisible.current))
}}
>
<Component_2_FirstSection />
</VisibilitySensor>
[ ... ]
<VisibilitySensor
onChange={(visible: boolean) => {
firstSectionCompsVisible.current = visible ? firstSectionCompsVisible.current + 1 : firstSectionCompsVisible.current - 1;
setActive(getMaxs(firstSectionCompsVisible.current, secondSectionCompsVisible.current, [ ... ], NSectionCompsVisible.current));
}}
>
<Component_N_FirstSection />
</VisibilitySensor>
</Grid>
</Grid>
/* Second section */
<Grid container justify="center" id="IdSecond">
<Grid item xs={8}>
<VisibilitySensor
onChange={(visible: boolean) => {
secondSectionCompsVisible.current = visible ? secondSectionCompsVisible.current + 1 : secondSectionCompsVisible.current - 1;
setActive(getMaxs(firstSectionCompsVisible.current, secondSectionCompsVisible.current, [ ... ], NSectionCompsVisible.current));
}}
>
<Component_1_SecondSection />
</VisibilitySensor>
<VisibilitySensor
onChange={(visible: boolean) => {
secondSectionCompsVisible.current = visible ? secondSectionCompsVisible.current + 1 : secondSectionCompsVisible.current - 1;
setActive(getMaxs(firstSectionCompsVisible.current, secondSectionCompsVisible.current, [ ... ], NSectionCompsVisible.current));
}}
>
<Component_2_SecondSection />
</VisibilitySensor>
[ ... ]
<VisibilitySensor
onChange={(visible: boolean) => {
secondSectionCompsVisible.current = visible ? secondSectionCompsVisible.current + 1 : secondSectionCompsVisible.current - 1;
setActive(getMaxs(firstSectionCompsVisible.current, secondSectionCompsVisible.current, [ ... ], NSectionCompsVisible.current));
}}
>
<Component_N_SecondSection />
</VisibilitySensor>
</Grid>
</Grid>
/* Section N here...*/
</Container>
</Layout>
);
}
尽管它运行良好,但实际上运行正常,我认为这不是正确的方法,因此这里的任何帮助将不胜感激...
谢谢!
Szz。