What I want to do is to avoid code duplication managing the response from the request that has been made and serving the output to the components throughout the useState.
In this case, as soon as the page is loaded useEffect is triggered. It makes the request and handles the response using setLoadedPlaces to set the data to searchedPlace and setMarker to set the data to markersMap.
If the user makes a new request, data is treated in the same way as with the useEffect function, the only difference is that the request is made with POST with a body attached.
I thought that make only one request would be sufficient but how?
Here there is a lot going on in both functions, I tried to extrapolate the result but returned a promise, which has to be handle with .then(() => {})
because is asynchronous, but how?
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]);
receivedInputs() which is triggered by a button
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);
}
};
It looks like you should just lift out this part into its own function:
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);
}
Then just call it:
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);
}
};
create a function that fetch and call that function in your useEffect hook and in your callback.
const Component = () => {
const fetch = aynsc () => { //... }
useEffect(() => { fetch() }, [])
searchSubmitHandler = () => { fetch() }
return {}
}
Ok, I managed the solution in this way, I considered Will Jenkins answer and added a then() method because it is returning a Promise. Which carries "response" as an argument if the request success.
// *** 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);
}
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.