当我使用 React hooks 和 React context 添加新帖子时,为什么我的状态会替换我的帖子

Why is my state replacing my posts when I add a new one using React hooks and React context

我正在创建一个新应用程序,我希望能够 post 向我的朋友更新。一个微博站点。

我想了解如何使用 React 挂钩和 React 的上下文更新应用 API。我创建了以下将状态作为值的提供程序...我希望能够添加一个新的 post 然后更新状态的 post 以便我不必获取再次使用数据库(使用 firestore)我真的想节省对数据库的调用...

基本上,当我在状态中调用 createNewPost 时,我希望能够更新状态的当前 posts 部分:state.posts 但是当我在 [= 之后更新状态时18=] 调用成功,我的整个 posts 数组由于某种原因被替换。不确定我可能做错了什么...

import { createContext, useState } from 'react';
import { createDoc, getWhere } from '../utils/database/db';

export const PostDataContext = createContext();

const SetDataContextProvider = ({ children }) => {
    const [state, setState] = useState({
        posts: [],
        timelinePosts: [],
        createNewPost: async (collection, payload) => {
            const doc = await createDoc(collection, payload)
            payload.id = doc?.doc?.id;
            updateStatePosts(payload);
            return doc;
        },
        getPostsByUserId: async (userId) => {
            const dataReceived = await getWhere('/posts', userId, 'userId')
            setState({ ...state, posts: dataReceived })
        }
    });
    const updateStatePosts = (payload) => {
        console.log('why is state posts empty?!', state);
        setState({ ...state, posts: [payload, ...state.posts] })
    }
    return <PostDataContext.Provider value={state}>
        {children}
    </PostDataContext.Provider>
}

export default SetDataContextProvider;

如果我不得不猜测,我会说您在您的状态中使用的 updateStatePosts 函数中有一个初始空 posts 状态的陈旧外壳。您可以使用功能状态更新来访问之前的状态以进行更新。功能状态更新允许您从以前的状态更新,而不是更新在 enqueued/enclosed 中的状态。

const SetDataContextProvider = ({ children }) => {
    const [state, setState] = useState({
        posts: [],
        timelinePosts: [],
        createNewPost: async (collection, payload) => {
            const doc = await createDoc(collection, payload)
            payload.id = doc?.doc?.id;
            updateStatePosts(payload);
            return doc;
        },
        getPostsByUserId: async (userId) => {
            const dataReceived = await getWhere('/posts', userId, 'userId')
            setState(prevState => ({
                ...prevState, // <-- preserve any previous state
                posts: dataReceived
            }))
        }
    });

    const updateStatePosts = (payload) => {
        setState(prevState => ({ // <-- previous state to this update
            ...prevState,
            posts: [payload, ...prevState.posts],
         }));
    };

    return <PostDataContext.Provider value={state}>
        {children}
    </PostDataContext.Provider>
}

这个函数是错误的:

const updateStatePosts = (payload) => {
        console.log('why is state posts empty?!', state);
        setState({ ...state, posts: [payload, ...state.posts] })
    }

您正确地使用了您所在州的展开运算符,但 posts 被直接替换了。您可能想使用以下 setState:

setState({ ...state, posts: [...payload,...state.posts] })

尽管如此,您还应该重构 state。函数不是状态,所以将它们放在你的状态之外。