You need to enable JavaScript to run this app. React Native 跳转至子页前列表状态更新异常问题排查
优惠活动
大模型
产品
解决方案
定价
更多

React Native 跳转至子页前列表状态更新异常问题排查

问题根因

你遇到的是典型的React闭包陷阱问题:

  • useLayoutEffect的依赖数组仅填写了navigation,只会在组件首次渲染时执行一次,给顶部导航栏设置的headerRight按钮绑定的是首次渲染时的handleOpenNewTask函数实例
  • 这个初始的函数实例闭包捕获的taskList永远是初始的空数组,后续taskList状态更新后,旧的函数实例不会同步感知到状态变化,因此每次点击新增按钮打印的都是旧值
  • 另外你的onTaskCreated函数也存在闭包问题,后续连续多次新增时也可能出现状态覆盖的情况

解决方案

按以下步骤修改代码即可:

  1. 用useCallback包裹回调函数,同时状态更新改用函数式写法,避免依赖外部状态
  2. 把handleOpenNewTask加入useLayoutEffect的依赖数组,状态变化后自动更新导航栏按钮的绑定事件

修改后完整代码

// Parent.js
import { useCallback } from 'react'

// 省略其他代码...

// 回调函数用useCallback包裹,状态更新用函数式写法避免依赖taskList
const onTaskCreated = useCallback(({ newTask, id }) => {
    setTaskList(prevTaskList => {
        // 基于上一次的最新状态更新,不会出现闭包旧值问题
        return [...prevTaskList, {value: id}]
    });
}, [setTaskList]);

// 用useCallback包裹,依赖变更时自动生成新的函数实例
const handleOpenNewTask = useCallback(() => {
    // 这里拿到的永远是最新的taskList
    console.log(taskList)
    navigation.navigate(routes.NEW_TASK, {
        onTaskCreated
    });
}, [navigation, onTaskCreated, taskList]); // 把用到的外部依赖都加进去

// 新增handleOpenNewTask作为依赖,状态更新后自动重设导航按钮
useLayoutEffect(() => {
    navigation.setOptions({
        headerRight: () => (
            <NewTaskHeaderRight onClick={handleOpenNewTask} />
        ),
    });
}, [navigation, handleOpenNewTask]);

额外优化点

如果不需要在handleOpenNewTask里读取taskList,可以把taskList从useCallback的依赖数组中移除,进一步减少不必要的导航栏更新。

内容的提问来源于stack exchange,提问作者denistepp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 18:15:05