反应JS useState进行快速事件

时间:2019-08-07 19:34:52

标签: reactjs

我正在尝试在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。

0 个答案:

没有答案