javascript 为什么useParams即使使用正确的语法也会返回undefined?

juzqafwq  于 2023-04-10  发布在  Java
关注(0)|答案(2)|浏览(108)

我知道这个问题已经被问了很多,但我读了每一个问题和答案,我的问题并没有消失。
我尝试访问http://localhost:3000/1useParams应该接收1以从API获取数据,但我接收到undefined
Component.tsx中,我使用console.log接收useParams,但我得到了undefined。所有相关文件都发布了,因为我正确使用了BrowserRouter和其他相关的React Router导入。
我的代码出了什么问题?为什么我没有得到正确的参数?
Component.tsx:

import { createContext, useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { CharacterSchema, PageSchema } from "../interfaces/characterInterfaces";
import { IGetAllCharacters } from "../interfaces/contextInterfaces";
import { IChildren } from "../interfaces/reactInterfaces";
import api from "../services/api";

export const GetAllCharactersContext = createContext<IGetAllCharacters>({} as IGetAllCharacters);

export const GetAllCharactersInfo = ({ children }: IChildren) => {
  const [charactersList, setCharactersList] = useState<CharacterSchema[]>([]);

  let navigate = useNavigate();

  const { page } = useParams();
  console.log(page);

  useEffect(() => {
    api
      .get(`/characters?page=${page}`)
      .then((res) => {
        setCharactersList(res.data.data);
        window.localStorage.setItem("lastPage", String(page));
        return res;
      })
      .catch((err) => console.error(err));
  }, [page]);

  const nextPage = () => {
    navigate(`/2`);
  };

  const prevPage = () => {
    navigate(`/1`);
  };

  return (
    <GetAllCharactersContext.Provider value={{ charactersList, nextPage, prevPage }}>
      {children}
    </GetAllCharactersContext.Provider>
  );
};

AllRoutes.tsx:

const AllRoutes = () => {
  return (
    <Routes>
      <Route path="/" element={<Navigate to="/1" />} />
      <Route path="/:page" element={<Home />} />
      <Route path="*" element={<Home />} />
    </Routes>
  );
};

export default AllRoutes;

index.tsx:

import React from "react";
    import ReactDOM from "react-dom/client";
    import App from "./App";
    import { BrowserRouter } from "react-router-dom";
    import Providers from "./contexts/Providers";
    
    const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement);
    root.render(
      <React.StrictMode>
        <BrowserRouter>
          <Providers>
            <App />
          </Providers>
        </BrowserRouter>
      </React.StrictMode>
    );
42fyovps

42fyovps1#

有了这个<Route path="/:page" element={<Home />} />,你就可以只在Home中使用pageuseParamsRoute为这个特定的url呈现的组件。
一种实现方法是在Home中移动获取部分。为此,将获取和更新状态的函数导出为上下文的一部分:

// ⚠️ Import what's needed
export const GetAllCharactersContext = createContext<IGetAllCharacters>({} as IGetAllCharacters);
export const GetAllCharactersInfo = ({ children }: IChildren) => {
  const [charactersList, setCharactersList] = useState<CharacterSchema[]>([]);
  const navigate = useNavigate();
  
  const fetchCharactersList = useCallback((page) => {
    api
      .get(`/characters?page=${page}`)
      .then((res) => {
        setCharactersList(res.data.data);
        window.localStorage.setItem("lastPage", String(page));
      })
      .catch((err) => console.error(err));
  }, []);

  const nextPage = () => {
    navigate(`/2`);
  };

  const prevPage = () => {
    navigate(`/1`);
  };

  return (
    <GetAllCharactersContext.Provider value={{ charactersList, fetchCharactersList, nextPage, prevPage }}>
      {children}
    </GetAllCharactersContext.Provider>
  );
};

然后将提供程序中的useEffect移动到Home中。类似这样:

// ⚠️ Import what's needed
export default function Home() {
  const { fetchCharactersList, charactersList } = useContext(GetAllCharactersInfo);
  const { page } = useParams();

  useEffect(() => {
    if (!page) return;
    fetchCharactersList(page);
  }, [page]);

  // render data
  return <div></div>;
}
oknwwptz

oknwwptz2#

我自己刚刚测试过这个。useParams需要在<Route>中使用,在这里指定了参数。它不只是从url中拉取它们。如果你想保持结构不变,我建议从你的上下文中公开一个页面设置器,并在可以访问钩子的组件中设置它。
或者,你可以使用useSearchParams,它实际上从url搜索参数本身获取数据,但你不能在url上使用它。

相关问题