首页 > 解决方案 > 刷新问题:使用路径名和 url 数组在 React/Gatsby 中设置下一个和上一个链接

问题描述

我正在使用一组链接进行分页,因为我希望它们按特定顺序排列。这一切都很好,如果我导航到我可以通过它们分页的任何功能页面;但是如果我刷新一个页面,Next href 默认为 [0] 或 'features/safety-training' 并且 Prev 最终是未定义的。我假设这与 useEffect 的工作原理有关,但我不确定如何解决它。

   const [position, setPosition] = useState(null);
   const [next, setNext] = useState(null);
   const [prev, setPrev] = useState(null);

     let theArray =[
        "/features/safetytraining", 
        "/features/certificatetracking", 
        "/features/policies", 
        "/features/standard-operating-procedures", 
        "/features/competencies", 
        "/features/contractor-orientations", 
        "/features/worksite-screening", 
        "/features/inspections", 
        "/features/incident-reporting", 
        "/features/behavior-observations", 
        "/features/bulletins", 
        "/features/suggestions", 
        "/features/polls", 
        "/features/whistleblower"
    ]

    useEffect(() => {

        let pathname = window.location.pathname

        //Check the array for pathname

        let checkPosition = theArray.indexOf(pathname);

       //Set the position to pathname index

        setPosition(checkPosition)

    });

       //Update next/prev when position changes

    useEffect(() => {

        setNext(theArray[position +1])

        setPrev(theArray[position -1])

    }, [position]);  


这是链接:

            <>
            <button 
            style={{marginRight: '15px'}}>
                <Link to={prev}>Prev</Link>
                </button>

            <button>
                <Link to={next}>Next</Link>
                </button>
            </> 

标签: arraysreactjsreact-hooksgatsbywindow.location

解决方案


您不需要任何状态或副作用 ( useEffect) :

// Pages don't change and don't depend on props or state,
// so let's define w/ `const` and extract from the
// component to avoid recreating on each render:
const pages = [
  "/features/safetytraining",
  "/features/certificatetracking",
  "/features/policies",
  "/features/standard-operating-procedures",
  "/features/competencies",
  "/features/contractor-orientations",
  "/features/worksite-screening",
  "/features/inspections",
  "/features/incident-reporting",
  "/features/behavior-observations",
  "/features/bulletins",
  "/features/suggestions",
  "/features/polls",
  "/features/whistleblower",
];

const Example = () => {
  // This is extraordinarily cheap to compute and will not
  // change without a re-render occurring, so we don't need
  // for it to be state:
  const position = typeof window === "undefined"
    ? 0
    : pages.indexOf(window.location.pathname);

  // Avoid using an invalid index position
  const prevPath = position <= 0 ? pages[pages.length] : pages[position - 1];
  const nextPath = position >= pages.length - 1 ? pages[0] : pages[position];

  return (
    <div>
      <button style={{ marginRight: "15px" }}>
        <Link to={prevPath}>Prev</Link>
      </button>

      <button>
        <Link to={nextPath}>Next</Link>
      </button>
    </div>
  );
};

您的原始代码产生了许多问题:

  • 每次调用 setter 函数(例如setPosition)时,React 都会将组件的重新渲染排入队列
  • 在初始渲染中positionprev、 和next都是null
  • 在进行服务器端渲染时,useEffect不会调用,因此您的链接会在初始加载时中断
  • 一旦组件安装在客户端,两个useEffect钩子都会被调用
    1. 第一个钩子会调用setPosition,提示重新渲染position设置的位置(prev并且next仍然是null);由于没有依赖数组,第一个钩子被再次调用,setPosition再次被调用
    2. 第二个钩子将被再次调用,因为positionchanged 和调用setPrevand setNext,提示另外两次重新渲染
    3. 在下一次渲染时,prev将设置但next不会
    4. 在下一次渲染中,next最终将按预期设置

推荐阅读