因此,我试图构建一个服务器端分页,它的工作方式类似于静态分页,我几乎做到了,但我遇到了一些似乎无法解决的问题.

这就是我的代码

const LiveIndex = (props) => {
  const [currentPage, setCurrentPage] = useState(0);
  const [isLoading, setLoading] = useState(false);
  const startLoading = () => setLoading(true);
  const stopLoading = () => setLoading(false);

  useEffect(() => {
    //After the component is mounted set router event handlers

    Router.events.on("routeChangeStart", startLoading);
    Router.events.on("routeChangeComplete", stopLoading);

    return () => {
      Router.events.off("routeChangeStart", startLoading);
      Router.events.off("routeChangeComplete", stopLoading);
    };
  }, []);

  const paginationHandler = (page) => {
    const currentPath = props.router.pathname;
    const currentQuery = props.router.query;
    currentQuery.page = currentPage + 1;

    props.router.push({
      pathname: currentPath,
      query: currentQuery,
    });
    setCurrentPage(currentQuery.page);
  };

  const backToLastPage = (page) => {
    const currentPath = props.router.pathname;
    const currentQuery = props.router.query;

    currentQuery.page = currentPage - 1;
    setCurrentPage(currentQuery.page); // THE code that breaks my code.

    props.router.push({
      pathname: currentPathh,
      query: currentQueryy,
    });
  };

  let content;
  if (isLoading) {
    content = (
      <div>
        <h2 class="loading-text">loading.</h2>
      </div>
    );
  } else {
    //Generating posts list

    content = (
      <div className="container">
        <h2> Live Games - </h2>

        <div className="columns is-multiline">
          <p>{props.games.name}</p>
        </div>
      </div>
    );
  }

  return (
    <>
      <div className={"container-md"}>
        <div>{content}</div>

        {props.games.length ? (
          <a onClick={() => paginationHandler(currentPage)}> moore </a>
        ) : (
          backToLastPage(currentPage)
        )}
      </div>
    </>
  );
};

export async function getServerSideProps({ query }) {
  const page = query.page || 1; //if page empty we request the first page
  const response = await fetch(
    `exampleapi.com?sort=&page=${page}&per_page=10&token`
  );

  const data = await response.json();
  return {
    props: {
      games: data,
    },
  };
}

export default withRouter(LiveIndex);

问题是我的backToLastPage很好地完成了这项工作,但我无法在该函数中使用setCurrentPage(),每次使用它时,我都会出现以下错误

Uncaught Invariant Violation: Too many re-renders. React limits the number of renders to prevent an infinite loop

如何在backToLast函数中更新currentPage state的值

非常感谢.

推荐答案

在JSX中直接调用backToLastPage,每次都会重新呈现/调用.和setCurrentPage个(useState个)触发器重新呈现backToLastPage个中的状态变化.

您可以想象,每次状态更改时,组件都会被渲染,它会再次设置状态,为组件进行无限渲染.

您可以使用useEffect来处理props.games个更改.这将帮助你在props.games发生变化时只触发backToLastPage一次.

React.useEffect(() => {
   if(!props.games || !props.games.length) {
      backToLastPage(currentPage)
   }
},[props.games])

可以进行完全修改

const LiveIndex = (props) => {
  const [currentPage, setCurrentPage] = useState(0);
  const [isLoading, setLoading] = useState(false);
  const startLoading = () => setLoading(true);
  const stopLoading = () => setLoading(false);

  useEffect(() => {
    //After the component is mounted set router event handlers

    Router.events.on("routeChangeStart", startLoading);
    Router.events.on("routeChangeComplete", stopLoading);

    return () => {
      Router.events.off("routeChangeStart", startLoading);
      Router.events.off("routeChangeComplete", stopLoading);
    };
  }, []);

  //The main change is here
  //It will be triggered whenever `props.games` gets updated
  React.useEffect(() => {
    if(!props.games || !props.games.length) {
      backToLastPage(currentPage)
    }
  },[props.games])

  const paginationHandler = (page) => {
    const currentPath = props.router.pathname;
    const currentQuery = props.router.query;
    currentQuery.page = currentPage + 1;

    props.router.push({
      pathname: currentPath,
      query: currentQuery,
    });
    setCurrentPage(currentQuery.page);
  };

  const backToLastPage = (page) => {
    const currentPath = props.router.pathname;
    const currentQuery = props.router.query;

    currentQuery.page = currentPage - 1;
    setCurrentPage(currentQuery.page); // THE code that breaks my code.

    props.router.push({
      pathname: currentPathh,
      query: currentQueryy,
    });
  };

  let content;
  if (isLoading) {
    content = (
      <div>
        <h2 class="loading-text">loading.</h2>
      </div>
    );
  } else {
    //Generating posts list

    content = (
      <div className="container">
        <h2> Live Games - </h2>

        <div className="columns is-multiline">
          <p>{props.games.name}</p>
        </div>
      </div>
    );
  }

  return (
    <>
      <div className={"container-md"}>
        <div>{content}</div>

        {props.games.length && (
          <a onClick={() => paginationHandler(currentPage)}> moore </a>
        )}
      </div>
    </>
  );
};

export async function getServerSideProps({ query }) {
  const page = query.page || 1; //if page empty we request the first page
  const response = await fetch(
    `exampleapi.com?sort=&page=${page}&per_page=10&token`
  );

  const data = await response.json();
  return {
    props: {
      games: data,
    },
  };
}

export default withRouter(LiveIndex);

Javascript相关问答推荐

通过在页面上滚动来移动滚动条

在拖放时阻止文件打开

TypeError:无法读取未定义的属性(正在读取';宽度';)

如何 for each 输入动态设置输入变更值

搜索功能不是在分页的每一页上进行搜索

如何在FastAPI中为通过file:/URL加载的本地HTML文件启用CORS?

如何为仅有数据可用的点显示X轴标签?

如何在尚未创建的鼠标悬停事件上访问和着色div?

如何在Jest中模拟函数

是否设置以JavaScript为背景的画布元素?

如何在TransformControls模式下只保留箭头进行翻译?

固定动态、self 调整的优先级队列

正则表达式以确定给定文本是否不只包含邮箱字符串

在传单的图像覆盖中重新着色特定 colored颜色 的所有像素

如何使用useparams从react路由中提取id

单击时同时 Select 和展开可访问的行

Oracle APEX-如何调用Java脚本函数

使用Java脚本的响应页面

ReactJS -使用useRef和将变量放在组件之外有什么区别?

重新定位类元素