【问题标题】:redux state doesn't have updated value in InterSectionObserver callback functionRedux 状态在 In​​terSectionObserver 回调函数中没有更新值
【发布时间】:2022-01-03 05:34:59
【问题描述】:

我正在使用IntersectionObserver api 来实现无限滚动。当callback被调用时,则在callback内部,redux状态没有更新值。函数是:

//function for defining InfiniteScroll
const InfiniteScroll = (parent,target,options,callback,getObject)=>{
    const Infoptions = {
        root: parent,
        rootMargin: '50px',
        threshold: 1.0,
        ...options
      }
      
      let observer = new IntersectionObserver(callback, Infoptions);
      observer.observe(target);      
      getObject(observer);
      
}


export default InfiniteScroll;


这里用到了这个函数:

//calling InfiniteScroll
    const target = useRef();
    const parent = useRef();
    const observer = useRef();
    const state = useSelector((state)=>state);

    useEffect(() => {
        if(!loading){
            
            InfiniteScroll(parent.current, target.current, {}, callbackScroll, function (obs) {
                observer.current = obs;
            })
        }
        return () => {
            observer.current&&observer.current.disconnect();
        }
    }, [loading])

    const callbackScroll = useCallback((data, observer) => {
        
        if (data[0].isIntersecting) {
            if ((state.post.data[postid]?.hasmorecomments) !== false){
                //if there are more comments ,then this function will call api to fetch comments
                FetchPostComments();
                //here (state.post.data[postid]) returns undefined value,
                //which is the initial value(when component has not mounted),
                //but in some_other function ,it returns updated value
                console.log((state.post.data[postid]));
            }
        }
    },[FetchPostComments])    
 

const some_other = ()=>{
   //here it logs expected value(an object,not undefined)
   console.log(state.post.data[postid]);
}

我想要 callbackScroll 函数中的更新值,就像函数 some_other 一样。我怎样才能实现它?

Edit-1 : 使用目标的 jsx 代码

//parent is the reference to scrollable div   
return (
     <div ref={parent}>
           <Comments/>
           {//here too, state.post.data[postid] has updated value}
           {((state.post.data[postid]?.hasmorecomments) !== false)&&<Loader/>}
            <div ref={target}></div>
     </div>
)

【问题讨论】:

  • 可以在使用target的地方添加代码吗?
  • @RahulSharma 嗨,我已经编辑了这个问题。

标签: javascript reactjs react-redux redux-toolkit intersection-observer


【解决方案1】:

使用useCallback的目的是避免每次父组件或自身重新渲染时不必要的函数调用,这是通过返回回调函数的记忆版本来实现的,该回调函数仅在状态时调用或依赖数组中的参考值发生变化。 useCallback 中的函数仅在组件最初以初始状态值安装时执行一次。 因此,它返回undefined。您希望它在状态更新时再次执行(即,在这种情况下,当状态更新以包含更多 cmets 时调用该函数)。您只需将状态包含在 useCallback 挂钩的依赖数组中即可完成此操作。

const callbackScroll = useCallback((data, observer) => {
        
        if (data[0].isIntersecting) {
            if ((state.post.data[postid]?.hasmorecomments) !== false){
                //if there are more comments ,then this function will call api to fetch comments
                FetchPostComments();
                //here (state.post.data[postid]) returns undefined value,
                //which is the initial value(when component has not mounted),
                //but in some_other function ,it returns updated value
                console.log((state.post.data[postid]));
            }
        }
    },[FetchPostComments,state]) //Include state in dependency array

【讨论】:

  • 试过了还是不行!!!
  • 在我将 parent,target,callbackScrollobserver 包含在 useEffect 依赖项中后工作
  • 啊,没错。由于卸载/挂载还依赖于observer 和其他相关实例,因此也需要包含这些依赖项。
【解决方案2】:

问题基本上在于useEffectuseCallback的依赖数组

useEffect(() => {
        if(!loading){
            
            InfiniteScroll(parent.current, target.current, {}, callbackScroll, function (obs) {
                observer.current = obs;
            })
        }
        return () => {
            observer.current&&observer.current.disconnect();
        }
    }, [loading,parent,target,callbackScroll,observer])

const callbackScroll = useCallback((data, observer) => {
        
        if (data[0].isIntersecting) {
            if ((state.post.data[postid]?.hasmorecomments) !== false){
                //if there are more comments ,then this function will call api to fetch comments
                FetchPostComments();
                //here (state.post.data[postid]) returns undefined value,
                //which is the initial value(when component has not mounted),
                //but in some_other function ,it returns updated value
                console.log((state.post.data[postid]));
            }
        }
    },[FetchPostComments,state]) //Include state in dependency array

【讨论】:

    猜你喜欢
    • 2018-07-21
    • 2021-09-08
    • 1970-01-01
    • 2020-10-31
    • 2019-01-28
    • 2021-03-21
    • 2018-09-23
    • 2017-01-24
    • 2018-03-08
    相关资源
    最近更新 更多