Как обработать запрос и избежать дублирования кода? - PullRequest
1 голос
/ 08 марта 2020

То, что я хочу сделать, - это избежать дублирования кода, управлять ответом на запрос, который был сделан, и передавать выходные данные компонентам в течение всего состояния useState.

В этом случае, как только страница загружен useEffect срабатывает. Он делает запрос и обрабатывает ответ, используя setLoadedPlaces, чтобы установить для данных поисковый запрос, и setMarker, чтобы установить для данных markersMap.

Если пользователь делает новый запрос, данные обрабатываются так же, как и с помощью useEffect. Единственное отличие состоит в том, что запрос выполняется с помощью POST с прикрепленным телом.

Я думал, что будет достаточно сделать только один запрос, но как?

Здесь много чего происходит в обеих функциях я пытался экстраполировать результат, но возвращал обещание, которое должно обрабатываться с .then(() => {}), потому что оно асинхронно, но как?

  const [searchedPlaces, setLoadedPlaces] = useState();
  const [MarkersMap, setMarkersMap] = useState();

useEffect ()

    useEffect(() => {
        const fetchPlaces = async () => {
          try {
            const responseData = await sendRequest(
              "http://localhost:5000/api/search"
            );

            //here I assign the data to setsetLoadedPlaces

            setLoadedPlaces(responseData.elements);

            //here I extrapolate lng and lat and assign to setMarkersMap

            let locations = [];
            responseData.elements.map(element => {
            element.location.lat = parseFloat(element.location.lat);
            element.location.lng = parseFloat(element.location.lng);
              locations.push(element.location);
              return locations;
            });
            setMarkersMap(locations);
          } catch (err) {}
        };
        fetchPlaces();
      }, [sendRequest]);

receiveInputs (), которое вызывается кнопкой

const receivedInputs = async val => {
    console.log(val.address);
    try {
        let responseData = await fetch("http://localhost:5000/api/search?", {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify({
                address: val.address.value.toLowerCase(),
                price: val.price.value.toLowerCase(),
                leaseTime: val.leaseTime.value.toLowerCase()
            })
        });

        let fetchPlaces = await responseData.json();

        //here I assign the data to setsetLoadedPlaces

        setLoadedPlaces(fetchPlaces.elements);

        //here I extrapolate lng and lat and assign to setMarkersMap

        let locations = [];
        fetchPlaces.elements.map(element => {
            element.location.lat = parseFloat(element.location.lat);
            element.location.lng = parseFloat(element.location.lng);
            locations.push(element.location);
            return locations;
        });

        setMarkersMap(locations);

    } catch (err) {
        console.log(err);
    }
};

Ответы [ 3 ]

0 голосов
/ 08 марта 2020

создайте функцию, которая извлекает и вызывает эту функцию в вашем хуке useEffect и в вашем обратном вызове.

const Component = () => {

const fetch = aynsc () => { //... }

useEffect(() => { fetch() }, [])

searchSubmitHandler = () => { fetch() }

return {}

}
0 голосов
/ 09 марта 2020

Хорошо, я справился с решением таким образом, я рассмотрел Will Jenkins ответ и добавил метод then (), потому что он возвращает Promise. Который несет «ответ» в качестве аргумента при успешном выполнении запроса.

  //                              ***      useEffect      ***

useEffect(() => {
    const fetchPlaces = async () => {
      try {
        const responseData = await sendRequest(
          "http://localhost:5000/api/search"
        );

        return responseData;
      } catch (err) {}
    };
    fetchPlaces().then(response => {
      handleResponseData(response);
    });
  }, [sendRequest]);

  //                              ***      Request      ***

  const receivedInputs = async val => {
    try {
      let responseData = await fetch("http://localhost:5000/api/search?", {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          address: val.address.value.toLowerCase(),
          price: val.price.value.toLowerCase(),
          leaseTime: val.leaseTime.value.toLowerCase()
        })
      });
      return responseData.json().then(response => {
        handleResponseData(response);
      });
    } catch (err) {
      console.log(err);
    }
  };
0 голосов
/ 08 марта 2020

Похоже, вам следует просто поднять эту часть в ее собственную функцию:

const handleResponseData = responseData => {
    setLoadedPlaces(responseData.elements);
    const locations = responseData.elements.map(element => {
          element.location.lat = parseFloat(element.location.lat);
          element.location.lng = parseFloat(element.location.lng);
          return element;
    });
   setMarkersMap(locations);
}  

Затем просто вызвать ее:

 useEffect(() => {
    const fetchPlaces = async () => {
      try {
        const responseData = await sendRequest(
          "http://localhost:5000/api/search"
        );

       handleResponseData(responseData)
      } catch (err) {}
    };
    fetchPlaces();
  }, [sendRequest]);


const SearchSubmitHandler = async event => {
    event.preventDefault();
    try {
      let responseData = await fetch("http://localhost:5000/api/search?", {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          address: formState.inputs.address.value.toLowerCase(),
          price: formState.inputs.price.value.toLowerCase(),
          leaseTime: formState.inputs.leaseTime.value.toLowerCase()
        })
      });

      handleResponseData(responseData.json())

    } catch (err) {
      console.log(err);
    }
  };
...