Javascript 状态不会用React钩子更新
我以为我的头被钩子钩住了。然而,我正在努力解决这个问题。下面的代码是我实际演示代码的一个非常简化的版本。实际上,Javascript 状态不会用React钩子更新,javascript,reactjs,closures,react-hooks,Javascript,Reactjs,Closures,React Hooks,我以为我的头被钩子钩住了。然而,我正在努力解决这个问题。下面的代码是我实际演示代码的一个非常简化的版本。实际上,clickHandler()和upload()要复杂得多。这就是为什么不能将它们组合成一个函数的原因。问题是我无法从upload函数中的状态访问更新的文件数组。但是,如果我对数组使用ref,它就会工作,我认为它是一个反模式。我还试图在组件外部声明状态,但没有成功。谢谢你的帮助 import React, { useCallback, useState } from 'react';
clickHandler()
和upload()
要复杂得多。这就是为什么不能将它们组合成一个函数的原因。问题是我无法从upload函数中的状态访问更新的文件数组。但是,如果我对数组使用ref,它就会工作,我认为它是一个反模式。我还试图在组件外部声明状态,但没有成功。谢谢你的帮助
import React, { useCallback, useState } from 'react';
const HomeScreen = () => {
const initialState = {
error: false,
files: [],
totalSize: 0,
finished: false
};
const [state, setState] = useState(initialState);
const upload = useCallback(() => {
// At this point state.files is an empty array
console.log(state.files);
}, [state]);
const clickHandler = useCallback(() => {
const queue = [
{ id: 1, bool: false },
{ id: 2, bool: false }
];
setState((state) => {
return { ...state, files: queue }
});
upload()
}, [upload]);
return <button onClick={clickHandler}>Click me</button>;
};
export default HomeScreen;
import React,{useCallback,useState}来自“React”;
常量主屏幕=()=>{
常量初始状态={
错误:false,
文件:[],
总大小:0,
完成:错误
};
常量[状态,设置状态]=使用状态(初始状态);
const upload=useCallback(()=>{
//此时state.files是一个空数组
console.log(state.files);
},[州];
常量clickHandler=useCallback(()=>{
常量队列=[
{id:1,bool:false},
{id:2,bool:false}
];
设置状态((状态)=>{
返回{…状态,文件:队列}
});
上传()
},[上传];
返回点击我;
};
导出默认主屏幕;
使用钩子状态更新程序进行状态更新是异步的,因此当您从clickHandler
中调用upload时,更新的状态对您不可用。将状态传递给upload方法的最简单解决方案
import React, { useCallback, useState } from 'react';
const HomeScreen = () => {
const initialState = {
error: false,
files: [],
totalSize: 0,
finished: false
};
const [state, setState] = useState(initialState);
const upload = useCallback((updatedState) => {
// At this point state.files is an empty array
console.log((updatedState || state).files);
}, [state]);
const clickHandler = useCallback(() => {
const queue = [
{ id: 1, bool: false },
{ id: 2, bool: false }
];
setState((state) => {
const updatedState = { ...state, files: queue }
upload(updatedState )
return updatedState;
});
upload()
}, [upload]);
return <button onClick={clickHandler}>Click me</button>;
};
export default HomeScreen;
import React,{useCallback,useState}来自“React”;
常量主屏幕=()=>{
常量初始状态={
错误:false,
文件:[],
总大小:0,
完成:错误
};
常量[状态,设置状态]=使用状态(初始状态);
const upload=useCallback((updatedState)=>{
//此时state.files是一个空数组
log((updatedState | | state).files);
},[州];
常量clickHandler=useCallback(()=>{
常量队列=[
{id:1,bool:false},
{id:2,bool:false}
];
设置状态((状态)=>{
const updatedState={…状态,文件:队列}
上载(updatedState)
返回updatestate;
});
上传()
},[上传];
返回点击我;
};
导出默认主屏幕;
使用钩子状态更新程序进行状态更新是异步的,因此当您从clickHandler
中调用upload时,更新的状态对您不可用。将状态传递给upload方法的最简单解决方案
import React, { useCallback, useState } from 'react';
const HomeScreen = () => {
const initialState = {
error: false,
files: [],
totalSize: 0,
finished: false
};
const [state, setState] = useState(initialState);
const upload = useCallback((updatedState) => {
// At this point state.files is an empty array
console.log((updatedState || state).files);
}, [state]);
const clickHandler = useCallback(() => {
const queue = [
{ id: 1, bool: false },
{ id: 2, bool: false }
];
setState((state) => {
const updatedState = { ...state, files: queue }
upload(updatedState )
return updatedState;
});
upload()
}, [upload]);
return <button onClick={clickHandler}>Click me</button>;
};
export default HomeScreen;
import React,{useCallback,useState}来自“React”;
常量主屏幕=()=>{
常量初始状态={
错误:false,
文件:[],
总大小:0,
完成:错误
};
常量[状态,设置状态]=使用状态(初始状态);
const upload=useCallback((updatedState)=>{
//此时state.files是一个空数组
log((updatedState | | state).files);
},[州];
常量clickHandler=useCallback(()=>{
常量队列=[
{id:1,bool:false},
{id:2,bool:false}
];
设置状态((状态)=>{
const updatedState={…状态,文件:队列}
上载(updatedState)
返回updatestate;
});
上传()
},[上传];
返回点击我;
};
导出默认主屏幕;
要使您的upload()
函数能够访问当前状态,必须从useffect()
调用该函数。看看这对你有用吗
const主屏幕=()=>{
常量初始状态={
错误:false,
文件:[],
总大小:0,
完成:错误
};
const[state,setState]=React.useState(initialState);
const upload=React.useCallback(()=>{
//此时state.files是一个空数组
console.log(state.files);
},[州];
React.useffect(()=>{
state.files.length?upload():null;
},[州];
const clickHandler=React.useCallback(()=>{
常量队列=[
{id:1,bool:false},
{id:2,bool:false}
];
设置状态((状态)=>{
返回{…状态,文件:队列}
});
//上传()
},[上传];
返回点击我;
};
ReactDOM.render(,document.getElementById('root'))代码>
要使您的upload()
函数能够访问当前状态,必须从useffect()
调用该函数。看看这对你有用吗
const主屏幕=()=>{
常量初始状态={
错误:false,
文件:[],
总大小:0,
完成:错误
};
const[state,setState]=React.useState(initialState);
const upload=React.useCallback(()=>{
//此时state.files是一个空数组
console.log(state.files);
},[州];
React.useffect(()=>{
state.files.length?upload():null;
},[州];
const clickHandler=React.useCallback(()=>{
常量队列=[
{id:1,bool:false},
{id:2,bool:false}
];
设置状态((状态)=>{
返回{…状态,文件:队列}
});
//上传()
},[上传];
返回点击我;
};
ReactDOM.render(,document.getElementById('root'))代码>
感谢您的快速回答。我也考虑过这一点,并尝试添加一些超时,但也不起作用。你能解释一下原因吗?这是因为setTimeout函数中有一个新的闭包吗?谢谢你的快速回答。我也考虑过这一点,并尝试添加一些超时,但也不起作用。你能解释一下原因吗?是因为setTimeout函数中有一个新的闭包吗?