#reactjs #react-hooks
Вопрос:
Мне нужно отправить GET
запросы и POST
запросы на многие конечные точки.
Например, GET | POST
Список Фруктов GET | POST
, Список Погоды…
Не на одной странице, они разделены(Маршрут браузера). например) Страница Фруктов, Страница Погоды…
Я хотел бы знать, как сделать так, чтобы пользователь реагировал в этой ситуации.
Я много искал, но все записи были основаны на одной конечной точке api.
Способ 1
Создайте повторно используемую функцию выборки.
function useGetFetch(url){
const response = await fetch(url, ...
return response.json()
}
function usePostFetch(url){
const response = await fetch(url, ...
return response.json()
}
Способ 2
Создайте функцию по одной для каждого.
function getFruitList(){
const response = await fetch('/fruit', ...
}
function postFruitList(){
const response = await fetch('/fruit', ...
}
function getWeatherList(){
const response = await fetch('/weather', ...
}
function postWeatherList(){
const response = await fetch('/weather', ...
}
Комментарии:
1. На мой взгляд, даже если второй способ может показаться менее СУХИМ , он будет лучше масштабироваться и его будет легче поддерживать. Вы можете создать «уровень обслуживания», где мы сохраняем эти различные функции выборки, которые вызываются из a
useEffect
в маршруте/компоненте, в котором они необходимы. Первый способ может выглядеть хорошо, потому что в нем меньше кода, но при таком подходе вы обязуетесь всегда связывать все конечные точки вместе по этому пути, что может привести к проблемам в будущем.2. то, что я сделал однажды, — это завернул
fetch
, чтобы разместить варианты, которые я должен был разместить. если вам нужна информация о пользователе и вы используете контекстный api, использование крючка позволяет легко использовать пользователя из контекста.3. @AlexanderNied Основываясь на вашем мнении, я думаю, что чем больше конечных точек, тем более управляемый способ2. Спасибо вам за ваше мнение.
4. Добро пожаловать-объединение этого с подходом @Noriller к абстрагированию фактических битов выборки в крючок, вероятно, даст вам лучшее из обоих миров (возможность повторного использования общих частей без ненужной связи). Удачи, счастливого кодирования!
Ответ №1:
Я как-то читал о useAsync
крюке Кента и думаю, что ваш второй подход подойдет хорошо. Вот весь код того, что входит в создание многоразового useAsync
хука с помощью примера API star-wars :-
import "./styles.css";
import React, { useEffect } from "react";
export default function App() {
const {
run: starShipExec,
status: starshipStatus,
data: starshipData,
error: startshipError
} = useAsync({ status: "idle" });
const {
run: peopleExec,
status: peopleStatus,
data: peopleData,
error: peopleError
} = useAsync({ status: "idle" });
useEffect(() => {
starShipExec(getStarships());
peopleExec(getPeople());
}, [starShipExec, peopleExec]);
return (
<div className="App">
Startships
<ul>
{starshipData?.results.map((res) => (
<li>{res.name}</li>
))}
</ul>
People
<ul>
{peopleData?.results.map((res) => (
<li>{res.name}</li>
))}
</ul>
</div>
);
}
async function getStarships() {
return await fetch("https://swapi.dev/api/starships");
}
async function getPeople() {
return await fetch("https://swapi.dev/api/people");
}
function asyncReducer(_state, action) {
switch (action.type) {
case "pending": {
return { status: "pending", data: null, error: null };
}
case "resolved": {
return { status: "resolved", data: action.data, error: null };
}
case "rejected": {
return { status: "rejected", data: null, error: action.error };
}
default: {
throw new Error(`Unhandled action type: ${action.type}`);
}
}
}
function useSafeDispatch(dispatch) {
const mountedRef = React.useRef(false);
React.useLayoutEffect(() => {
mountedRef.current = true;
return () => (mountedRef.current = false);
}, []);
const safeDispatch = React.useCallback(
(...args) => {
mountedRef.current amp;amp; dispatch(...args);
},
[dispatch]
);
return safeDispatch;
}
function useAsync({ status }) {
const [state, unsafeDispatch] = React.useReducer(asyncReducer, {
status: status,
data: null,
error: null
});
const dispatch = useSafeDispatch(unsafeDispatch);
const run = React.useCallback(
(promise) => {
if (!promise) {
return;
}
dispatch({ type: "pending" });
promise
.then((data) => data.json())
.then((data) => {
dispatch({ type: "resolved", data });
})
.catch((error) => {
dispatch({ type: "rejected", error });
});
},
[dispatch]
);
return { ...state, run };
}
Та часть, которая мне нравится, возвращает run
функцию, в которую мы можем передать любое обещание, а остальное управляет крючок. Это дает пользователю API больше контроля над тем, что выполнять.
Вот рабочий код и коробка :-