Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
150
rated 0 times [  151] [ 1]  / answers: 1 / hits: 6292  / 3 Years ago, sat, july 10, 2021, 12:00:00

I'm using Axios to get, put, and delete values from our database and have them displayed in a table; however, I need to refresh the page to see my changes. To find answers, I've visited these posts: How to update the page after call Axios Successful ? React, refresh table after action in react, and How can I use React Hooks to refresh a table when a row is deleted or added?
Unfortunately, I am still stuck and unsure how to dynamically update table rows upon response updates.


Update: I have noticed that the getValues function runs prior to the post and delete methods, which is why it is currently showing the previous values before the methods execute.


Axios.js - Where I am using get and delete methods. They work as I've had responses printed on the console.


import axios from "axios";

const getValues = async () => {
const values = await axios
.get("https://pokeapi.co/api/v2/type/")
.then((response) => {
return response.data;
})
.catch(function (error) {
console.log(error);
});
return values;
};


const postValues = (values) => {
axios
.post("https://pokeapi.co/api/v2/type/")
.then((response) => {
console.log("Post Values: ", response.data);
return response.data;
});
};

const deleteValues = (id) => {
console.log(id);
const deleteValues = axios
.delete(`https://pokeapi.co/api/v2/type/${id}`)
.then((response) => {
console.log("Delete Values: ", response);
})
.catch(function (error) {
console.log(error);
});
return deleteValues;
};

export { getValues, postValues, deleteValues }

ValuesTable.js - Where the delete method executes


  import Axios from "./Axios";

const [data, setData] = React.useState();

useEffect(() => {
Axios.getValues().then((result) => {
setData(result.data);
});
}, [data]);

return (
{data.map((values) => {
<TableRow/>
<TableCell>{values.values}</TableCell>
<TableCell>
<Button
onClick={() =>
Axios.deleteValues(values.id);
}
/>
})};
)

Form.js - Where the post method executes


if (values.id === 0) {
Axios.postValues(values);
} else {
Axios.putValues(values, values.id);
}

UseState setData(result.data) loads all the existing values in the database.
Method deleteValues deletes a value in an array.
Method postValues adds a value into the database.


More From » reactjs

 Answers
1

Well, you don't what to unconditionally call setData within an useEffect hook with data as a dependency as this will cause an infinite loop (render looping) to occur.


Since the getValues utility already unpacks the response.data value there is likely no need to do it again in your UI. Also, remove the data dependency.


useEffect(() => {
Axios.getValues()
.then((result) => {
setData(result.results);
});
}, []);

For the deleteValues utility, if console.log("Delete Values: ", response); is showing the correct values than I think you need to return this value from deleteValues.


const deleteValues = (id) => {
console.log(id);
const deleteValues = axios
.delete("https://pokeapi.co/api/v2/type/${id}`)
.then((response) => {
console.log("Delete Values: ", response);
return response; // <-- new data values
})
.catch(function (error) {
console.log(error);
});
return deleteValues;
};

Then in ValuesTable you need to update your data state with the new deleted values.


{data.map((values) => {
...
<Button
onClick={() => {
Axios.deleteValues(values.id)
.then(data => setData(data));
}}
/>
...
})};

Update


Ok, since the deleteValues utility doesn't return the updated data from the backend you will need to maintain your local state manually. I suggest doing this work in a callback handler. Upon successful deletion, update the local state.


const [data, setData] = React.useState();

useEffect(() => {
Axios.getValues().then((result) => {
setData(result.data);
});
}, []);

const deleteHandler = id => async () => {
try {
await Axios.deleteValues(id); // no error, assume success
setData(data => data.filter((item) => item.id !== id));
} catch(err) {
// whatever you want to do with error
}
};

return (
...
{data.map((values) => {
<TableRow/>
<TableCell>{values.values}</TableCell>
<TableCell>
<Button onClick={deleteHandler(values.id)}>
Delete
</Button>
})};
...
)

Note that I've written deleteHandler to be a curried function so you don't need an anonymous callback function for the button's onClick handler. It encloses the current id in an "instance" of the callback.


Update 2


If you are making a lot of different changes to your data in the backend it may just be easier to use a "fetch" state trigger to just refetch ("get") your data after each backend update. Anytime you make a call to update data in your DB, upon success trigger the fetch/refetch via a useEffect hook.


const [data, setData] = React.useState();
const [fetchData, setFetchData] = useState(true);

const triggerDataFetch = () => setFetchData(t => !t);

useEffect(() => {
Axios.getValues().then((result) => {
setData(result.data);
});
}, [fetchData]);

const deleteHandler = id => async () => {
try {
await Axios.deleteValues(id); // no error, assume success
triggerDataFetch(); // <-- trigger refetch
} catch(err) {
// whatever you want to do with error
}
};

[#1120] Saturday, July 3, 2021, 3 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
minab

Total Points: 701
Total Questions: 104
Total Answers: 91

Location: Saint Pierre and Miquelon
Member since Fri, Jan 28, 2022
2 Years ago
minab questions
Tue, Oct 1, 19, 00:00, 5 Years ago
Thu, Jul 25, 19, 00:00, 5 Years ago
Fri, Apr 19, 19, 00:00, 5 Years ago
;