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

React Native Expo中Jotai atom始终为null的问题求助

Jotai Atom设置后仍为null的问题解决

问题根源

React的状态更新(包括Jotai基于React实现的atom更新)是异步批量处理的。你在handle函数里调用setOrganisation(json)后,组件不会立刻重新渲染,此时organisation还是更新前的null值,直接访问organisation!!.token自然会触发空值错误。

快速修复

既然你已经拿到了json这个更新后的数据,没必要急着从atom读取,直接用json就行:

const handle = async ({data}: BarCodeEvent) => {
  const json: AttachResponse = JSON.parse(data);

  if (json.organisation == undefined || json.token == undefined) {
    alert(i18n.t('alerts.scan.invalid'));
    return;
  }

  await write("user", json)
  setOrganisation(json)
  console.log("StepThree json " + json.token)
  // 直接用已有的json,不用读atom
  console.log("StepThree org " + json.token)
}

后续逻辑处理(如果需要在状态更新后执行)

如果必须在atom更新完成后做操作,可以用useEffect监听atom的变化:

import { useAtom, useAtomValue } from 'jotai'

export const HomeScreen = () => {
  const [, setOrganisation] = useAtom(organisationAtom)
  const organisation = useAtomValue(organisationAtom)

  // 监听organisation变化,更新后执行逻辑
  useEffect(() => {
    if (organisation) {
      console.log("StepThree org " + organisation.token)
      // 这里放状态更新后的业务逻辑
    }
  }, [organisation])

  const handle = async ({data}: BarCodeEvent) => {
    const json: AttachResponse = JSON.parse(data);

    if (json.organisation == undefined || json.token == undefined) {
      alert(i18n.t('alerts.scan.invalid'));
      return;
    }

    await write("user", json)
    setOrganisation(json)
    console.log("StepThree json " + json.token)
  }

  return <Scanner onScanned={(data) => handle(data)}/>
}

为什么重启应用后正常?

重启时App组件的useAsyncEffect从安全存储读取数据并设置atom,此时组件会完成重新渲染,organisation已经是更新后的有效值,所以访问organisation.token不会有问题。而扫码时是在同一个渲染周期内调用setOrganisation,还没等到组件重新渲染就读取旧值,才会报错。

额外注意点

  • 确保organisationAtom是全局唯一的(你的state.ts写法没问题,不要在组件内部重复定义)。
  • 确认write("user", json)写入成功,避免后续重启读取失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 02:10:29