Javascript 如何将函数传递到自己的react上下文提供程序中,以便您编辑状态?
我有以下代码:Javascript 如何将函数传递到自己的react上下文提供程序中,以便您编辑状态?,javascript,reactjs,react-hooks,react-context,react-state,Javascript,Reactjs,React Hooks,React Context,React State,我有以下代码: import React,{useState}来自“React” export const NumberContext=React.createContext() 导出函数NumberProvider({children}){ 常量[numbers,setNumbers]=useState([]) 函数addNumber(number){ 常量副本=[…数字] 复制。推送(数字) 设置编号(副本) } 返回( {儿童} ) } 导出函数App(){ 返回( ) } 导出函数d
import React,{useState}来自“React”
export const NumberContext=React.createContext()
导出函数NumberProvider({children}){
常量[numbers,setNumbers]=useState([])
函数addNumber(number){
常量副本=[…数字]
复制。推送(数字)
设置编号(副本)
}
返回(
{儿童}
)
}
导出函数App(){
返回(
)
}
导出函数displayNumber(){
常量[numbers,addNumbers]=useContext(NumberContext)
返回({numbers})
}
如果我现在通过提供程序中的上下文api调用addNumber()
函数,如下所示
导出函数AlterNumbers(){
常量[numbers,addNumber]=useContext(NumberContext)
函数号(){
地址编号(1)
设置超时(()=>{
地址号码(2)
}, 3000)
}
返回()
}
数字
等于[2]
而不是[1,2]
我的提供程序函数
NumberProvider
中的状态与NumberContext.provider
中的状态不一样。我怎样才能防止这种情况发生?实现这一点的设计模式是什么样子的?因为useState
的setter是异步的,一个调用会覆盖另一个调用:
const NumberConsumer = () => {
const [numbers, addNumber] = useContext(NumberContext);
addNumber(1); // Will update numbers to [1] in "future"
setTimeout(() => { // Will update numbers to [2] in "future"
addNumber(2); // The call within the timeout,
// is not aware of the previous state
}, 3000);
return <h1>{JSON.stringify(numbers)}</h1>;
};
如注释中所述,您应该使用useffect
将逻辑更改为更健壮的逻辑:
export function ToastProvider({ children }) {
const [toasts, setToasts] = useState([])
const [key, setKey] = useState(0)
function showToast(label, message) {
setKey(key + 1)
setToasts([
...toasts,
{
key,
label,
message,
},
])
}
useEffect(() => {
setTimeout(() => {
const copy = [...toasts]
copy.pop()
setToasts(copy)
}, 5000)
}, toasts);
return (
<ToastContext.Provider value={[toasts, showToast]}>
{children}
</ToastContext.Provider>
)
}
将函数导出到提供程序({children}){
const[toasts,setToasts]=useState([])
const[key,setKey]=useState(0)
函数showToast(标签、消息){
设置键(键+1)
敬酒([
…干杯,
{
钥匙
标签,
消息
},
])
}
useffect(()=>{
设置超时(()=>{
const copy=[…干杯]
copy.pop()
setToasts(副本)
}, 5000)
},敬酒);
返回(
{儿童}
)
}
将整个代码而不是片段放入组件函数体中。addNumber
调用是否在组件函数体中?是的,确切地说,它们在组件函数体中,而组件函数体位于自定义数字提供者组件内请更新您的问题,显示整个代码,预期的行为是什么,为什么在函数体中?是否要计算渲染的数量?详细说明。使用functionaluseState
,并尝试解释您想做得更好的地方,如果没有更多信息,很难提出建议。我真正想要实现的是在我的应用程序中为Toast(通知消息)创建一个消息队列。祝酒者应该被推到队列中,并在一段时间后被移走。我想通过上下文api从代码中的任何地方推送它们。在另一个地方,我想映射队列并显示当前在此队列中的所有消息。这是我的实际代码库:,我的主要问题是,我的自定义上下文提供程序中的useState似乎没有正确更新。您应该使用带有useEffect
的副作用,并将其从队列中删除。我更新了答案,请参阅
export function ToastProvider({ children }) {
const [toasts, setToasts] = useState([])
const [key, setKey] = useState(0)
function showToast(label, message) {
setKey(key + 1)
setToasts([
...toasts,
{
key,
label,
message,
},
])
}
useEffect(() => {
setTimeout(() => {
const copy = [...toasts]
copy.pop()
setToasts(copy)
}, 5000)
}, toasts);
return (
<ToastContext.Provider value={[toasts, showToast]}>
{children}
</ToastContext.Provider>
)
}