我以为我的脑袋钩在钩子上。但是,我正在为此苦苦挣扎。下面的代码是我用于演示的实际代码的非常简化的版本。实际上,clickHandler()
和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;
答案 0 :(得分:0)
状态更新是异步的,因此,当您从clickHandler
内调用上载时,更新的状态对您不可用。将状态传递给上载方法的最简单解决方案
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;
答案 1 :(得分:0)
要使您的upload()
函数能够访问当前状态,必须从useEffect()
进行调用。看看这对您有用吗?
const HomeScreen = () => {
const initialState = {
error: false,
files: [],
totalSize: 0,
finished: false
};
const [state, setState] = React.useState(initialState);
const upload = React.useCallback(() => {
// At this point state.files is an empty array
console.log(state.files);
}, [state]);
React.useEffect(()=>{
state.files.length ? upload() : null;
},[state]);
const clickHandler = React.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>;
};
ReactDOM.render(<HomeScreen/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>