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);
Use 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);
use Object.values
instead of Object.entries
.
Also, merge new res with the previous res.
const data = Object.entries(book);
setBooks(books => [...books, ...data]);
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.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script> <div id="react"></div> <div id="app"></div>
Never recommended to mutate the state directly.
The recommended 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]
}))
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.