在history.listen的useEffect中使用useState挂钩

时间:2019-10-27 00:06:03

标签: javascript reactjs typescript react-hooks

在听useState中的history更改时,我在useEffect上遇到了麻烦。

pathname发生更改时,将启动setState,然后又重新添加state

例如,我有一个flag组件,用于收集多组通知,但是在进行pathname更改时,我希望所有标志都从state中删除并删除。

标志组件

const PageFlag = ({ history }: InterfaceProps) => {
const { contextData, dismissFlag, dismissAllFlags } = useContext(GlobalConsumer);

  useEffect(() => {
    history.listen(() => {
      dismissAllFlags();
    });
  });

  return (
    <>
      <FlagGroup onDismissed={dismissFlag}>
        {contextData.flags.map((flag, index) => (
          <Flag key={index} {...flag} />
        ))}
      </FlagGroup>
    </>
  );
};

import { withRouter } from 'react-router-dom'开始使用历史道具

dismissAllFlags的状态和功能在createContext组件中显示为

const DefaultState: InterfaceState = {
  otherStateExample: false,
  flags: []
};

export const GlobalConsumer = createContext({
  contextData: DefaultState,
  addFlag: (flagData: any) => {},
  dismissFlag: () => {},
  dismissAllFlags: () => {}
});

export const GlobalProvider = ({ children }: InterfaceProps) => {
  const [state, setState] = useState<InterfaceState>({
    ...DefaultState
  });

  return (
    <GlobalConsumer.Provider
      value={{
        contextData: state,
        addFlag: (flagData: any) => {
          setState({ ...state, flags: [flagData].concat(state.flags) });
        },
        dismissFlag: () => {
          setState({ ...state, flags: state.flags.slice(1) });
        },
        dismissAllFlags: () => {
          setState({ ...state, flags: [] });
        }
      }}
    >
      {children}
    </GlobalConsumer.Provider>
  );
};

出现问题,在pathname发生更改时,dismissAllFlags使用setStateflags设置为[],然后用{ {1}}。

如何删除所有flags,但记得其他flags的当前state

3 个答案:

答案 0 :(得分:1)

您缺少useEffect()上的第二个输入参数,这将导致在每个渲染器上都读取侦听器。

它应该看起来像这样,注意您也不需要内部函数。

useEffect(() => {
  history.listen(dismissAllFlags)
}, []);

答案 1 :(得分:1)

我们这样使用它:

cd /d "%~dp0"

答案 2 :(得分:0)

如果我理解您的要求是什么

  

您希望将标志设置为一个空数组,而不必使用当前正在使用的class CommentList(generics.ListCreateAPIView): queryset = Comment.objects.filter(post=???) serializer_class = CommentSerializer 的split方法添加以前的值。

好吧,使用urlpatterns = [ ... path('posts/<int:pk>/comments/', CommentList.as_view()) ] 不可能做到这一点,并且对于嵌套状态对象要当心,因为对于较大的对象来说克隆会变得很昂贵。 也许这就是您想要避免的地方

即使您切换到{...state, flags: []},您仍将最终为该州散布道具。

也许您应该仅将标志设置为自己的状态useState或查看immutable-helper

此外, 尝试尊重useReducer其他妻子,有趣的事情可能开始发生。如果没有部门,则至少给您的钩子一个空数组,以确保执行一次。