当我使用 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
。函数不是状态,所以将它们放在你的状态之外。
我正在创建一个新应用程序,我希望能够 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
。函数不是状态,所以将它们放在你的状态之外。