I have the following situation. I am fetching data from the backend and the response is a bunch of objects. I want to iterate into them and in every iteration, I want to push them into my state.
here is how I am getting data from the backend:
const allBookings = useSelector(getBookings);
useEffect(() => {
dispatch(
fetchBookings.request({
getAll: true,
})
);
}, [dispatch]);
here is my data:
bookings:{
0:{id: 294, address: '1585 Charleston Rd, Mountain View, CA, USA', broker:{name:'aaa'}},
1:{id: 294, address: '1586 Charleston Rd, Mountain View, CA, USA', broker:{name:'bbb'}},
2:{id: 294, address: '1587 Charleston Rd, Mountain View, CA, USA', broker:{name:'ccc'}}
}
Here where I am trying to set my data in an array, but something goes wrong, please help me to figure out how I can achieve. The final result should be like this:
[
{id: 294, address: '1585 Charleston Rd, Mountain View, CA, USA', broker:{name:'aaa'}},
{id: 294, address: '1586 Charleston Rd, Mountain View, CA, USA', broker:{name:'bbb'}},
{id: 294, address: '1587 Charleston Rd, Mountain View, CA, USA', broker:{name:'ccc'}}
]
if (!allBookings) return null;
const book = allBookings.bookings;
const [books, setBooks] = useState([]);
useEffect(() => {
if (book) {
const x = Object.entries(book);
setBooks(x);
}
}, [book]);
console.log('books===>', books);
here is my code in sandbox
I have the following situation. I am fetching data from the backend and the response is a bunch of objects. I want to iterate into them and in every iteration, I want to push them into my state.
here is how I am getting data from the backend:
const allBookings = useSelector(getBookings);
useEffect(() => {
dispatch(
fetchBookings.request({
getAll: true,
})
);
}, [dispatch]);
here is my data:
bookings:{
0:{id: 294, address: '1585 Charleston Rd, Mountain View, CA, USA', broker:{name:'aaa'}},
1:{id: 294, address: '1586 Charleston Rd, Mountain View, CA, USA', broker:{name:'bbb'}},
2:{id: 294, address: '1587 Charleston Rd, Mountain View, CA, USA', broker:{name:'ccc'}}
}
Here where I am trying to set my data in an array, but something goes wrong, please help me to figure out how I can achieve. The final result should be like this:
[
{id: 294, address: '1585 Charleston Rd, Mountain View, CA, USA', broker:{name:'aaa'}},
{id: 294, address: '1586 Charleston Rd, Mountain View, CA, USA', broker:{name:'bbb'}},
{id: 294, address: '1587 Charleston Rd, Mountain View, CA, USA', broker:{name:'ccc'}}
]
if (!allBookings) return null;
const book = allBookings.bookings;
const [books, setBooks] = useState([]);
useEffect(() => {
if (book) {
const x = Object.entries(book);
setBooks(x);
}
}, [book]);
console.log('books===>', books);
here is my code in sandbox
Share Improve this question edited Dec 28, 2021 at 9:12 Bourbia Brahim 14.7k4 gold badges43 silver badges54 bronze badges asked Dec 28, 2021 at 8:49 someonesomeone 6911 gold badge6 silver badges26 bronze badges 1-
Since you already have
allBookings
why add the same entries in local state ? You can use theallBookings
directly. Additionally you cannot use hooks conditionally, meaning that you cannot have a branch likeif (..) return null;
and then add auseXXX
hook after that line. – Gabriele Petrioli Commented Dec 28, 2021 at 9:09
5 Answers
Reset to default 2Use functional update to push new entires into your books
array:
const x = Object.entries(book);
setBooks(books => [...books, ...x]);
Since you’re always instantiating with an empty array you also don’t need the falsy check, ie you can remove if (books)
.
change const x = Object.entries(book)
; to const x = Object.values(book);
In your useEffect
use the store selector var to watch changes ,
also you shouldn't use Object.entries in your case , instead use Object.values ,
Object.entries will get both key and values , and put them as an array for each entry like
[["0",{id: 294, address: '1585 Charleston Rd,...}]]
but Object.values
wil only create new array from values ( your objects )
your code should looks like
const [books, setBooks] = useState([]);
useEffect(() => {
if (allBookings.bookings) {
const entries = Object.values(allBookings.bookings);
setBooks(entries);
}
}, [allBookings]);
Try the below Snippet :
// Get a hook function
const {useState, useEffect } = React;
const Example = ({title}) => {
let serverObject = {
bookings:{
0:{id: 294, address: '1585 Charleston Rd, Mountain View, CA, USA', broker:{name:'aaa'}},
1:{id: 294, address: '1586 Charleston Rd, Mountain View, CA, USA', broker:{name:'bbb'}},
2:{id: 294, address: '1587 Charleston Rd, Mountain View, CA, USA', broker:{name:'ccc'}}
}
}
const [allBookings, setAllBookings] = useState({});
const [books, setBooks] = useState([]);
setTimeout(()=> { setAllBookings(serverObject)}, 2000)
useEffect(() => {
if (allBookings.bookings) {
const entries = Object.values(allBookings.bookings);
setBooks(entries);
}
}, [allBookings]);
return (
<div>
{
books.map( book => <p> {book.address} </p>)
}
</div>
);
};
// Render it
ReactDOM.render(
<Example title="Example using Hooks:" />,
document.getElementById("app")
);
<script src="https://cdnjs.cloudflare./ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
<div id="app"></div>
use Object.values
instead of Object.entries
.
Also, merge new res with the previous res.
const data = Object.entries(book);
setBooks(books => [...books, ...data]);
Never remended to mutate the state directly.
The remended approach in later React versions is to use an updater function when modifying states to prevent race conditions:
For Functional Components
const [array,setArray] = useState([]);
Push value at the end:
setArray(oldArray => [...oldArray,newValue] );
Push value at the beginning:
setArray(oldArray => [newValue,...oldArray] );
For Class Components
Push string to end of the array, you do this...
this.setState(prevState => ({
myArray: [...prevState.myArray, "new value"]
}))
Push string to beginning of the array, you do it like this ...
this.setState(prevState => ({
myArray: ["new value", ...prevState.myArray]
}))
Push object to end of the array, you do this ...
this.setState(prevState => ({
myArray: [...prevState.myArray, {"name": "object"}]
}))
Push object to beginning of the array, you do this ....
this.setState(prevState => ({
myArray: [ {"name": "object"}, ...prevState.myArray]
}))