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 нет картинок, и я их добавлял в ручную, поэтому конечный массив называется по другому
  • Вопрос задан
  • 98 просмотров
Решения вопроса 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, то данные пока не загрузились, надо подождать.

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

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

Войти через центр авторизации
Похожие вопросы