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
解决方案
同步
sub与用户ID状态sub来自状态管理,可能是异步加载的,组件初始化时sub还未获取到,导致useState初始值为undefined。需要监听sub的变化来更新状态:useEffect(() => { const newUserId = sub || 'anon'; setUserId(newUserId); setCurrentUserId(newUserId); }, [sub]);移除useState中直接用
sub作为初始值的写法,因为useState初始值仅在首次渲染生效,无法响应sub后续的更新。修复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变化时才会重新查询,不会触发无限循环。正确查看异步更新后的状态
useState的setter是异步的,调用setTasks后立刻console.log(tasks)拿到的是旧值。如需查看更新后的值,可单独加一个监听useEffect:useEffect(() => { console.log('更新后的tasks:', tasks); }, [tasks]);移除冗余的状态设置
删除getFormikDefaultValues中的setCurrentUserId调用,因为已通过监听sub的useEffect同步该状态,避免重复操作。
内容的提问来源于stack exchange,提问作者ibbs

