代码之家  ›  专栏  ›  技术社区  ›  Darren

useEffect不会在路由更改时更新状态

  •  0
  • Darren  · 技术社区  · 6 年前

    我正在寻找一个解决方案来注册路线更改并应用新的 state setState useEffect . 下面的当前代码不更新的函数 当路线改变时。

    例如,我注册了 pathname / 具有 location.pathname === '/' 在内部 createContext ,如果 / 这个 属于 isHome 注册 true 路径名 /page-1 注册 false .

    在浏览器重新加载时, onMount 但是,在路线更改时,使用 Link 但事实并非如此。另外,请注意,我使用的是盖茨比,在这样做时,输入 { Link } from 'gatsby'

    CreateContext.js

    export const GlobalProvider = ({ children, location }) => {
    
    
    const prevScrollY = useRef(0);
      const [state, setState] = useState({
        isHome: location.pathname === '/',
        // other states
      });
    
      const detectHome = () => {
        const homePath = location.pathname === '/';
        if (!homePath) {
          setState(prevState => ({
            ...prevState,
            isHome: false
          }));
        }
        if (homePath) {
          setState(prevState => ({
            ...prevState,
            isHome: true
          }));
        }
      };
    
      useEffect(() => {
        detectHome();
        return () => {
          detectHome();
        };
      }, [state.isHome]);
    
      return (
        <GlobalConsumer.Provider
          value={{
            dataContext: state,
          }}
        >
          {children}
        </GlobalConsumer.Provider>
      );
    };
    

    如果我 console.log(state.isHome) 路径名 我明白了 真的 假的 但是,如果我更改路线,当前 讨厌的 状态保持在前一状态,直到我滚动并 应用。

    讨厌的 状态是改变每页的CSS。

    使用效果 当改变路线时。以前,我会这样做的 componentDidUpdate 登记 prevProps.location.pathname 反对 props.location.pathname 然而,我的理解是,这对于 使用效果 钩子。

    0 回复  |  直到 6 年前
        1
  •  4
  •   Mohamed Ramrami    6 年前

    useEffect 代码如下:

      useEffect(() => {
        detectHome();
        return () => {
          detectHome();
        };
      }, [location]);
    
        2
  •  1
  •   Alex Gessen    6 年前

    如果您正在使用react路由器,您可以在useEffect中订阅位置更改事件:

    import {browserHistory} from 'react-router';
    
    ...
    useEffect(() => {
      return browserHistory.listen(detectHome);
    }, []);
    ...
    
    

    detectHome 用于装载时更改位置和卸载时取消订阅的功能。

        3
  •  0
  •   Fuechter    6 年前

    我想如果你用 GlobalProvider

      useEffect(() => {
        detectHome();
        return () => {
          detectHome();
        };
      }, [state.isHome]);
    

    上面的代码 state 仅此更新 useEffect detectHome 返回的内部 使用效果 仅在发生其他更新或 state.isHome 和第一次不一样。这个解释有点混乱,但事实就是这样。

    但解决方案是使用窗口的“popstate”事件:

    export const GlobalProvider = ({ children, location }) => {
    
    
    const prevScrollY = useRef(0);
      const [state, setState] = useState({
        isHome: location.pathname === '/',
        // other states
      });
    
      const detectHome = () => {
        const homePath = location.pathname === '/';
        if (!homePath) {
          setState(prevState => ({
            ...prevState,
            isHome: false
          }));
        }
        if (homePath) {
          setState(prevState => ({
            ...prevState,
            isHome: true
          }));
        }
      };
    
      useEffect(() => {
        window.addEventListener('popstate', detectHome)
        return () => {
          window.removeEventListener('popstate', detectHome)
        };
      }, [state.isHome]);
    
      return (
        <GlobalConsumer.Provider
          value={{
            dataContext: state,
          }}
        >
          {children}
        </GlobalConsumer.Provider>
      );
    };
    

    我认为盖茨比应该操纵历史,所以这会引起轰动 popstate 您可以检测url的更改。