微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

useSWR hook 行为不正常或可能过时的关闭

如何解决useSWR hook 行为不正常或可能过时的关闭

我有一个 React 功能组件,它以与 Instagram 故事非常相似的方式呈现课程视频播放器。课程中的某些视频(“剪辑”)具有“互动”,会弹出一张卡片,用户可以在其中回答多项选择题。代码简化如下。

随机课程中,一些互动没有显示。在日志 interactions 1 中,它们像往常一样显示(记录一堆未定义的值,然后在几次重新渲染后记录数组)但是当 onClipEnding 函数调用interactions 2 再次未定义。

关于可能发生什么的任何线索?我最好的猜测是一个陈旧的闭包,但我找不到解决它的方法

export function getInteractions(lesson_id: string,profile_id?: string) {
  const { data,error } = useSWR<ManyResponse<Interaction>>(
    `${apiRoutes.interactions}/${lesson_id}?per_page=50${
      profile_id ? `&profile_id=${profile_id}` : ''
    }`,request,)

  return {
    interactions: data && data.data,isLoading: !data && !error,error,}
}

export default function LessonPlayer({ videoIds }) {
  const setVideos = useStoreActions((actions: Actions<Store>) => actions.setVideos)
  const { interactions } = getInteractions(lessonId,currentProfileId)
  console.log('interactions 1',interactions)

  useEffect(() => {
    if (!videoIds && videos) {
      setVideos(videos)
    }
  },[videoIds,setVideos])

  return (
    <>
      <div>
        {(videoIds || []).map((videoId) => (
          <Video key={videoId} videoId={videoId} onEnd={onClipEnding} />
        ))}
      </div>
      {interactions && (
        <div className="absolute bottom-0 w-full">
          <InteractionCard interaction={interaction} handleInteraction={handleInteraction} />
        </div>
      )}
    </>
  )

  function onClipEnding(videoId: string) {
    const clipInteraction = interactions && interactions.find((item) => item.clip_id == videoId)
    console.log('interactions 2',interactions)
    if (clipInteraction) {
      setInteraction(clipInteraction)
    } else {
      nextClip({ profile_id: currentProfileId,status: 'completed' })
    }
  }

解决方法

这是在初始渲染时创建的 onClipEnding 的陈旧闭包,它捕获值为 interactionsundefined 变量,然后作为回调传递给 <Video />通过它的 onEnd 道具。在那里,它在初始渲染时保留为陈旧版本,直到被调用才更新。

既然您知道过时的关闭问题,我相信以上信息应该足以让您进行调试。剩下的就交给你了。

奖励:我与您分享我的秘密武器,这是解决过时关闭问题的灵丹妙药。输入 useFn 自定义钩子:

function useFn(fn) {
  const ref = useRef(fn);
  ref.current = fn;

  function wrapper() {
    return ref.current.apply(this,arguments)
  }

  return useRef(wrapper).current
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?