使用长时间运行的任务和合并状态来反应useEffect挂钩

时间:2019-05-11 08:35:05

标签: javascript reactjs rxjs react-hooks

我有一个场景,用户可以使用拖放功能上传文件。

我将效果与空数组配合使用来设置RXJS订阅,该订阅处理已删除的文件和上载时间:

const [attachments, setAttachments] = useState([])

useEffect(() => {
    ...
    fileUploadSubject.subscribe(newAttachments => {
       setAttachments([...attachments,newAttachments])
    })
    ...
    return () => {
      subscriptions.forEach(s => {
        s.unsubscribe()
      })
    }
},[])

问题在于效果与attachmentssetAttachments函数有关。

如果我将attachments添加到依赖项数组,我将退订现有的上载。同样,attachment状态由于其关闭而不会在效果内更新。

如何解决这种情况?我想到了多种方法,但似乎找不到简单的前进方法。

2 个答案:

答案 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>;
}

我仍然认为您的效果不依赖任何东西很奇怪,请确保subscriptionsfileUploadSubject确实不应该位于依赖关系数组中。

答案 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太难了。

相关问题