Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ReactJS如何仅在向下滚动并到达页面上的组件时才呈现该组件?_Javascript_Reactjs_React Chartjs - Fatal编程技术网

Javascript ReactJS如何仅在向下滚动并到达页面上的组件时才呈现该组件?

Javascript ReactJS如何仅在向下滚动并到达页面上的组件时才呈现该组件?,javascript,reactjs,react-chartjs,Javascript,Reactjs,React Chartjs,我有一个react组件Data,它包括几个图表组件条形图线形图等 当Data组件开始渲染时,需要一段时间才能从API接收每个图表所需的数据,然后它开始响应并渲染所有图表组件 我需要的是,当我向下滚动并到达页面上的图表时,只开始渲染每个图表 有什么方法可以帮助我实现这个目标吗 您至少有三种选择: 跟踪组件是否在视口中(用户可见)。然后渲染它。你可以用这个 用鼠标明确跟踪“y”滚动位置 使用Intersection Observer API编写自己的HOC 要呈现组件,您可能需要另一个HOC,它将根

我有一个react组件
Data
,它包括几个图表组件<代码>条形图
线形图

Data
组件开始渲染时,需要一段时间才能从API接收每个图表所需的数据,然后它开始响应并渲染所有图表组件

我需要的是,当我向下滚动并到达页面上的图表时,只开始渲染每个图表


有什么方法可以帮助我实现这个目标吗

您至少有三种选择:

  • 跟踪组件是否在视口中(用户可见)。然后渲染它。你可以用这个

  • 用鼠标明确跟踪“y”滚动位置

  • 使用Intersection Observer API编写自己的HOC


  • 要呈现组件,您可能需要另一个HOC,它将根据收到的道具返回图表组件或“null”。

    您可以检查窗口滚动位置,如果滚动位置靠近您的div,则显示它。 为此,可以使用简单的react渲染条件

    import React, {Component} from 'react';
    import PropTypes from 'prop-types';
    
    class MyComponent extends Component {
    constructor(props){
        super(props);
    
        this.state = {
            elementToScroll1: false,
            elementToScroll2: false,
        }
    
        this.firstElement = React.createRef();
        this.secondElement = React.createRef();
    }
    componentDidMount() {
        window.addEventListener('scroll', this.handleScroll);
    }
    
    componentWillUnmount() {
        window.removeEventListener('scroll', this.handleScroll);
    }
    handleScroll(e){
        //check if scroll position is near to your elements and set state {elementToScroll1: true}
        //check if scroll position is under to your elements and set state {elementToScroll1: false}
    }
    render() {
        return (
            <div>
                <div ref={this.firstElement} className={`elementToScroll1`}>
                    {this.state.elementToScroll1 && <div>First element</div>}
                </div>
                <div ref={this.secondElement} className={`elementToScroll2`}>
                    {this.state.elementToScroll2 && <div>Second element</div>}
                </div>
            </div>
        );
    }
    }
    
    MyComponent.propTypes = {};
    
    export default MyComponent;
    
    import React,{Component}来自'React';
    从“道具类型”导入道具类型;
    类MyComponent扩展组件{
    建造师(道具){
    超级(道具);
    此.state={
    ElementToScroll 1:错误,
    ElementToScroll 2:错误,
    }
    this.firstElement=React.createRef();
    this.secondElement=React.createRef();
    }
    componentDidMount(){
    window.addEventListener('scroll',this.handleScroll);
    }
    组件将卸载(){
    window.removeEventListener('scroll',this.handleScroll);
    }
    handleScroll(东){
    //检查滚动位置是否靠近元素并设置状态{elementToScroll1:true}
    //检查滚动位置是否位于元素下方,并设置状态{elementtoscorl1:false}
    }
    render(){
    返回(
    {this.state.elementToScroll1&&First element}
    {this.state.elementToScroll2&&Second element}
    );
    }
    }
    MyComponent.propTypes={};
    导出默认MyComponent;
    

    这可能会帮助你,这只是一个快速的解决方案。它将为您生成一些重新加载操作,因此请注意。

    我尝试了许多库,但找不到最适合我需要的库,因此我为此编写了一个自定义挂钩,希望能有所帮助

    import { useState, useEffect } from "react";
    
    const OPTIONS = {
      root: null,
      rootMargin: "0px 0px 0px 0px",
      threshold: 0,
    };
    
    const useIsVisible = (elementRef) => {
      const [isVisible, setIsVisible] = useState(false);
    
      useEffect(() => {
        if (elementRef.current) {
          const observer = new IntersectionObserver((entries, observer) => {
            entries.forEach((entry) => {
              if (entry.isIntersecting) {
                setIsVisible(true);
                observer.unobserve(elementRef.current);
              }
            });
          }, OPTIONS);
          observer.observe(elementRef.current);
        }
      }, [elementRef]);
    
      return isVisible;
    };
    
    export default useIsVisible;
    
    然后你可以按如下方式使用钩子:

    import React, { useState, useEffect, useRef } from "react";
    import useVisible from "../../hooks/useIsVisible";
    
    function Deals() {
      const elemRef = useRef();
      const isVisible = useVisible(elemRef);
      return (
        <div ref={elemRef}>hello {isVisible && console.log("visible")}</div>
    )}
    
    import React,{useState,useffect,useRef}来自“React”;
    从“../../hooks/useIsVisible”导入useVisible;
    函数Deals(){
    const elemRef=useRef();
    const isVisible=useVisible(elemRef);
    返回(
    你好{isVisible&&console.log(“visible”)}
    )}
    
    我认为在React中实现这一点最简单的方法是使用

    例如:

    import { useInView } from 'react-intersection-observer';
    
    const Component = () => {
      const { ref, inView, entry } = useInView({
        /* Optional options */
        threshold: 0,
      });
    
      useEffect(()=>{
          //do something here when inView is true
      }, [inView])
    
      return (
        <div ref={ref}>
          <h2>{`Header inside viewport ${inView}.`}</h2>
         </div>
      );
    };
    
    从'react intersection observer'导入{useInView};
    常量组件=()=>{
    常量{ref,inView,entry}=useInView({
    /*可选选项*/
    阈值:0,
    });
    useffect(()=>{
    //当inView为真时,在这里做点什么
    },[inView])
    返回(
    {`视口内的标头${inView}.`}
    );
    };
    

    我还建议在options对象中使用
    triggerOnce:true
    ,这样效果只会在用户第一次滚动到它时发生。

    我从未尝试过,但可能会有所帮助。我使用了react visibility sensor而不是react in viewport,如下所示:
    onChange=(isVisible)=>{this.setState({isChart1Visible:isVisible});}render(){{{this.state.isChart1Visible?:null}}
    。但我仍然被困在如何渲染图表一旦图表在视口中!VisibilitySensor组件只接受显式子元素,不接受条件短语。我怎样才能解决这个问题?@Shatha你需要用react能见度传感器包装所有图表。下面是一个示例Thnx供您回答。实际上,我希望它是动态的,而不是检查每个图形的位置然后渲染它。因为我可能有很多图表,在每次代码更新期间,它们的位置可能会不同。这就是我使用react visibility sensor的原因,正如我在本文中介绍的,它检查元素是否在视图端口中。但我仍然无法在图表进入视口后渲染它