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

React Context返回null但useEffect返回对象,创建任务报user.id未定义

问题根因及修复方案

核心问题1:变量声明顺序错误

你在调用useState初始化target的时候,useAuth的解构赋值还没执行,此时user属于未声明变量,自然拿不到user.id的值。

核心问题2:state初始值绑定静态值,不会跟随Context更新

就算调整了声明顺序,user从Context拿到最新值后,已经初始化完成的state不会自动更新_partition的值。

核心问题3:state更新时丢失原有属性

React的useState setter不会自动合并对象属性,你在descriptionOnChange里只传入{description: value},会直接覆盖掉原有state里的_partition、_id等所有其他属性。

额外的打印日志问题

useEffect里用模板字符串包裹user对象,会自动调用对象的toString()方法,所以输出[object Object],直接写console.log('from create target', user)就能打印对象的实际内容。


修复后的代码

import React, {FC, SetStateAction, useEffect, useRef, useState} from 'react';
import {Text, View} from 'react-native';
import TButton from '../../components/button';
import Input from '../../components/input';
import {useAuth} from '../../lib/realmProvider';
import {useRealm} from '../../lib/syncProvider';
import {ITarget} from '../../lib/taskInterface';
import {Target} from '../../realm/taskSchema';
import {ObjectId} from 'bson';

const CreateTaskScreen: FC = () => {
  // 先调用useAuth拿到user,再初始化state
  const {user} = useAuth();
  const realm = useRealm();

  const [target, setTarget] = useState<Partial<ITarget>>({
    _id: '',
    _partition: '', // 初始值留空,等user加载完成后再更新
    description: '',
    status: false,
    createAt: new Date(Date.now()).toString(),
    updateAt: '',
  });

  // 监听user变化,更新state里的_partition
  useEffect(() => {
    if(user?.id) {
      setTarget(prev => ({...prev, _partition: user.id}));
    }
    console.log('from create target', user);
  }, [user]);

  const targetHandler = () => {
    // 提交前先校验_partition是否存在
    if(!target._partition) return console.log('用户信息未加载完成,请稍后重试');
    try {
      realm.write(() => {
        realm.create<Target>('Targets', {
          _id: new ObjectId(),
          _partition: target._partition,
          description: target.description,
          status: target.status,
          createAt: target.createAt,
          updateAt: target.updateAt,
        });
      });
    } catch (err) {
      console.log(err);
      throw err;
    }
  };

  const testHandler = () => {
    console.log(user);
  };

  const descriptionOnChange = (e: {nativeEvent: {text: SetStateAction}}) => {
    let value = e.nativeEvent.text;
    // 更新state时展开原有属性,避免丢失
    setTarget(prev => ({...prev, description: value}));
  };

  return (
    <View>
      <Text>Create a new Task</Text>
      <Input
        placeholder={'Targe Description'}
        onChange={descriptionOnChange}
        value={target.description}
        multiline={true}
      />
      <TButton title={'Add Target'} onPress={targetHandler} />
      <TButton title={'Test Button'} onPress={testHandler} />
    </View>
  );
};

export default CreateTaskScreen;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 08:54:07