Using useState hook in useEffect on history.listen

Dar*_*ren 1 javascript typescript reactjs react-hooks

I am having some troubles with useState when listening to history changes in useEffect.

When the pathname changes, setState is initiated but then the state is added back.

For example, I have a flag component that collects groups of notifications, but on the pathname change, I want all flags to be dismissed and removed from state.

The flag component

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>
    </>
  );
};
Run Code Online (Sandbox Code Playgroud)

History prop is used from import { withRouter } from 'react-router-dom'

The state and function for dismissAllFlags is shown in a createContext component as

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>
  );
};
Run Code Online (Sandbox Code Playgroud)

The problem arises, where on pathname change, dismissAllFlags uses setState to set flags as [] but then adds back the previous state with the flags.

How can I remove all flags but remember the current state for other items?

Dav*_*haw 7

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

它应该是这样的,注意你也不应该需要内部函数。

useEffect(() => {
  history.listen(dismissAllFlags)
}, []);
Run Code Online (Sandbox Code Playgroud)