I am trying to make an motor cycle social media using React.
when user search for a motorCycle model, it will show all the specs, as well as people who own the motor cycle, so that an user can reach out to them.
So, I am trying to pass all the owners list from a page to OwnersList.jsx as props, so that when the array of owners are ready(after fetching from MongoDB), OwnersList.jsx can show those people on the list.
I want it to show "LOADING..." when the prop array is empty, and as soon as the prop array is ready, I want it to re-render components.
However, even after the array arrives, the page is still showing "LOADING.." and it does't change.
What am I doing wrong here?
Also, that would be great if I can know what kind of basic concepts of React I am missing to be stuck in this kind of bug.
OwnersList.jsx
import React from "react";
import { useEffect, useState } from "react";
export default function OwnersList({ ownerObjectsArray }) {
useEffect(() => {
console.log(
"ownerObjectsArray.length is like this ",
ownerObjectsArray.length
);
}, [ownerObjectsArray]);
if (ownerObjectsArray.length === 0) {
console.log("yes, the array is empty. PLEASE WAIT");
return <h2>Loading...</h2>;
} else {
console.log("ownerObjectsArray is not empty, so , i will set it as state.");
return (
<div>
{ownerObjectsArray.map((ownerObject) => {
return (
<div key={ownerObject.username}>
<h3>{ownerObject.username}</h3>
<button>contact</button>
</div>
);
})}
OwnersList
</div>
);
}
}
Make use of the ternary operator ( condition ? result : else
) to conditionally render JSX inside of one return
statement.
Props changing will trigger a re-render so it will evaluate the ownerObjectsArray.length
again, and determine which JSX to render.
Shouldn't need more code than this:
import React from 'react'
export default function OwnersList({ ownerObjectsArray }) {
return ownerObjectsArray.length ? (
<div>
{ownerObjectsArray.map((ownerObject) => (
<div key={ownerObject.username}>
<h3>{ownerObject.username}</h3>
<button>contact</button>
</div>
))}
OwnersList
</div>
) : (
<h2>Loading...</h2>
)
}
There is one gotcha with "props changing". If the reference to the array doesn't change, then the re-render won't be triggered. So if you are just updating the same reference in the parent component, the child doesn't know that the array has changed.
Ex:
const ownerObjectsArray = []
// do some stuff
ownerObjectsArray.push(newObject)
The reference to the variable doesn't change, just one more addition to the same place in memory.
But, to create a new reference to the array, do something like this:
let ownerObjectsArray = []
// do some stuff
ownerObjectsArray = [...ownerObjectsArray, newObject]
Best yet, would be to control the array with useState
and pass the state down to the component:
[ownerObjectsArray, setOwnerObjectsArray] = useState([])
// do some stuff
setOwnerObjectsArray((prev) => [...prev, newObject])
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.