vladoosik1
@vladoosik1
react developer

Как Изменять конец ссылки API при переходе на разные страницы?

Делаю сайт по starwars, с одной бесплатной API, и у нее есть различные данные в зависимости от запроса. Всего у нее есть несколько категорий (films, people, starships, planets )и у меня на сайте есть такие вкладки. Вопрос, как сделать изменение API в зависимости от той вкладки в которой находишься ? Пытался разными способами, от useCallback и useState. до помещения на кнопку оператора onClick,
Вот код и не работающий метод,
const films = "films";
  const peoples = "people";
  const planets = "planets";
  const starshipsStr = "starships";

let [url, setUrl] = useState(`https://swapi.dev/api/${films}`);

let navigation = useLocation();

  useEffect(() => {
    if (navigation.pathname === "/films") {
      setUrl(`https://swapi.dev/api/${films}`);
      console.log("Вкладка фильмов", url);
    } else if (navigation.pathname === "/starships") {
      setUrl(`https://swapi.dev/api/${starshipsStr}`);
      console.log("Вкладка космических машин", url);
    } else if (navigation.pathname === "/people") {
      setUrl(`https://swapi.dev/api/${peoples}`);
      console.log("вкладка люди", url);
    } else if (navigation.pathname === "/planets") {
      setUrl(`https://swapi.dev/api/${planets}`);
      console.log("вкладка планет", url);
    } else {
      console.log("Ничего не работает");
    }
  }, []);

 useEffect(() => {
    fetch(url)
      .then((res) => res.json())
      .then((resp) => {
        setData(resp.results);
      });
  }, []);


return (
    <>
      <Routes>
        <Route
          element={
            <HeaderComponent
              data={ArrayBtn}
              width={120}
              height={120}
              color={"white"}
            />
          }
        >
          <Route exact path={"/"} element={<MainPage />} />
          <Route path={"/films"} element={<Films value={value} />} />
          <Route path={"/starships"} element={<StarCars value={value} />} />
          <Route path={"/planets"} element={<Planets value={value} />} />
          <Route path={"/peoples"} element={<Peoples value={value} />} />
        </Route>
      </Routes>
    </>
  );
}

P.s. метод useLocation() взял из Router-dom v6. Метод value это конечный массив с данными, по умолчанию в API нет картинок, и я их добавлял в ручную, поэтому конечный массив называется по другому
  • Вопрос задан
  • 99 просмотров
Решения вопроса 1
Alexandroppolus
@Alexandroppolus
кодир
Здесь абсолютно не нужен useState для url, потому как url зависит только от navigation.pathname и таким образом это просто вычисляемое значение. Из-за useState твой url "отстаёт на один рендер" от запроса данных - то есть на момент срабатывания useEffect с fetch значение url всегда "films". Потом ставится исправленный url, но fetch заново не вызывается - у него зависимости [].

Далее, надо учесть кейс, когда pathname может поменяться. Тогда надо перевызвать useEffect с fetch. Заодно есть смысл размещать данные в отдельных ячейках - это может предотвратить состояние гонки, плюс это будет легче типизировать.

Итого, упрощенно:
const {data, setData} = useState({});

const { pathname } = useLocation();
const apiPath = pathname === "/films" ? "films" :
       pathname === "/starships" ? "starships" :
       pathname === "/people" ? "people" :
       pathname === "/planets" ? "planets" : "";



useEffect(() => {
    const url = `https://swapi.dev/api/${apiPath}`;

    fetch(url)
      .then((res) => res.json())
      .then((resp) => {
        setData((data) => ({
           ...data,
           [apiPath]: resp.results,
        }));
      });
  }, [apiPath]);

.......
<Route path={"/films"} element={<Films value={data["films"]} />} />
.....


ну а внутри Films (и прочих) проверять что если value == null, то данные пока не загрузились, надо подождать.

можно ещё ошибку загрузки обработать, тут сам справишься.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы