我有一个场景,用户可以使用拖放功能上传文件。
我将效果与空数组配合使用来设置RXJS订阅,该订阅处理已删除的文件和上载时间:
const [attachments, setAttachments] = useState([])
useEffect(() => {
...
fileUploadSubject.subscribe(newAttachments => {
setAttachments([...attachments,newAttachments])
})
...
return () => {
subscriptions.forEach(s => {
s.unsubscribe()
})
}
},[])
问题在于效果与attachments
和setAttachments
函数有关。
如果我将attachments
添加到依赖项数组,我将退订现有的上载。同样,attachment
状态由于其关闭而不会在效果内更新。
如何解决这种情况?我想到了多种方法,但似乎找不到简单的前进方法。
答案 0 :(得分:2)
如果将附件添加到依赖项数组,我将退订现有的上载内容
不确定为什么取消订阅,不熟悉fileUploadSubject.subscribe
由于效果关闭,附件状态也未更新
您可以useReducer
代替useState
,这样就不必依赖效果的状态了。
也许是这样的:
function reducer(state, action) {
switch (action.type) {
case "ADD_ATTACH":
return [...state, action.payload];
default:
throw new Error();
}
}
function App() {
const [attachments, dispatch] = useReducer(reducer, []);
useEffect(() => {
// ...
fileUploadSubject.subscribe(newAttachments => {
dispatch({ type: "ADD_ATTACH", payload: newAttachments });
});
// ...
return () => {
subscriptions.forEach(s => {
s.unsubscribe();
});
};
}, [/*fileUploadSubject?, subscriptions? */]);
return <div>{ /* some UI */ }</div>;
}
我仍然认为您的效果不依赖任何东西很奇怪,请确保subscriptions
和fileUploadSubject
确实不应该位于依赖关系数组中。
答案 1 :(得分:2)
useState
的setState函数支持functional updates形式:
const [attachments, setAttachments] = useState([])
useEffect(() => {
...
const subscription = fileUploadSubject.subscribe(newAttachments => {
setAttachments((oldAttachments) => [...oldAttachments, newAttachments])
})
...
return () => subscription.unsubscribe()
}, [setAttachments, fileUploadSubject])
从不更改的功能(即在此两个都可以)可以在依赖项列表中省略,但是我更愿意列出它们以防止忘记某些依赖项。有eslint rules太难了。