You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中useState更新失效及useEffect配置问题求助

React Native中useState设置函数失效及useEffect依赖项问题

我在React Native中使用useState时,发现状态设置函数(setter)似乎无法正常工作。简化代码后仍可运行,但初始状态始终为undefined,setTasks和setCurrentUserId都存在这个问题。我知道useState是异步的,这可能影响渲染时机,但至少setCurrentUserId应该能成功设置。另外,如果把const [userId, setUserId] = useState(sub || 'anon')改成const [userId, setUserId] = useState(''),useEffect里的值也无法更新到userId。

同时我不确定该给useEffect设置什么依赖项:如果监听tasks的更新,会陷入无限循环。现在不知道该怎么推进,附上相关代码求助:

const individualJournal = () => {

    // State
    const sub = useAuthStore((state) => state.sub)
    const [userId, setUserId] = useState(sub || 'anon')
    const [tasks, setTasks] = useState<any>(null)
    const [taskId, setTaskId] = useState<any>()
    const [currentUserId, setCurrentUserId] = useState<string>(sub || 'anon')
    const [postsExists, setPostsExists] = useState(false)

    // Post related
    const getFormikDefaultValues = async (): void => {
        // Sets all the formik default values to pre populate fields
        // Will be run on rerender

        const newDefaultUsername = sub || 'anon'
        setCurrentUserId(newDefaultUsername)
    }

    const getPosts = async (): Promise<void> => {
        const posts: any = await database
            .get('posts')
            .query(Q.where('user_id', userId))
            .fetchCount()

        setPostsExists(false)
        if (posts > 0) {
            setPostsExists(true)
        }
    }

    useEffect(() => {
        async function setTasksFunc(): Promise<void> {
            const getTasks: any = await database
                .get('tasks')
                .query(
                    Q.where('is_completed', true),
                    Q.where('user_id', userId)
                )
            console.log(getTasks)
            setTasks(getTasks)
            console.log(tasks)
        }
        setTasksFunc()
        getPosts()
        setCurrentUserId(sub || 'anon')
    }, [])

    return (
        <TamaguiProvider config={config}>...</TamaguiProvider>
    )
}

export default individualJournal

解决方案

  1. 同步sub与用户ID状态
    sub来自状态管理,可能是异步加载的,组件初始化时sub还未获取到,导致useState初始值为undefined。需要监听sub的变化来更新状态:

    useEffect(() => {
      const newUserId = sub || 'anon';
      setUserId(newUserId);
      setCurrentUserId(newUserId);
    }, [sub]);
    

    移除useState中直接用sub作为初始值的写法,因为useState初始值仅在首次渲染生效,无法响应sub后续的更新。

  2. 修复useEffect数据查询逻辑
    原useEffect依赖为空数组,仅执行一次,此时userId可能未正确初始化,导致数据库查询出错。将userId加入依赖项,合并异步查询逻辑:

    useEffect(() => {
      async function fetchData() {
        // 查询帖子数量
        const postsCount = await database
          .get('posts')
          .query(Q.where('user_id', userId))
          .fetchCount();
        setPostsExists(postsCount > 0);
    
        // 查询任务列表
        const fetchedTasks = await database
          .get('tasks')
          .query(
            Q.where('is_completed', true),
            Q.where('user_id', userId)
          );
        setTasks(fetchedTasks);
      }
    
      fetchData();
    }, [userId]);
    

    这样仅当userId变化时才会重新查询,不会触发无限循环。

  3. 正确查看异步更新后的状态
    useState的setter是异步的,调用setTasks后立刻console.log(tasks)拿到的是旧值。如需查看更新后的值,可单独加一个监听useEffect:

    useEffect(() => {
      console.log('更新后的tasks:', tasks);
    }, [tasks]);
    
  4. 移除冗余的状态设置
    删除getFormikDefaultValues中的setCurrentUserId调用,因为已通过监听sub的useEffect同步该状态,避免重复操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 16:14:58