I'm trying to pass in an array of registered users into a component, however I can't because it always renders the initial empty array before actually rendering the correct content. I've tried using useRef and it still does not work.
const Home = () => {
const nav = useNavigate()
const [userList, setUserList] = useState([]);
const [loggedInUser, setLoggedInUser] = useState({});
const [currentChat, setCurrentChat] = useState(undefined);
const [showMenu, setShowMenu] = useState(false);
useEffect(() => {
const setLoggedIn = async() => {
if (!localStorage.getItem('loggedInUser')) {
nav('/');
} else {
setLoggedInUser(await JSON.parse(localStorage.getItem('loggedInUser')))
}
}
setLoggedIn().catch(console.error);
}, [])
useEffect(() => {
const fetchUsers = async () => {
const data = await axios.get(`${allUsersRoute}/${loggedInUser._id}`);
setUserList(data.data);
}
fetchUsers().catch(console.error);
}, [loggedInUser._id])
console.log(userList);
return (
<div id='container'>
<div id='sidebar'>
<div>
<div id='home-header'>
<h1>DevsHelp</h1>
</div>
<Userlist props={userList}/>
</div>
</div>
)};
And here is the component I'm trying to render.
const Userlist = (props) => {
return (
<div>
<div id='home-header'>
<h1>DevsHelp</h1>
</div>
<div id='userlist'>
{props.map((prop) => {
{console.log(props.length)}
return (
<div className='user'>
<h3>{prop.username}</h3>
</div>
)
})}
</div>
</div>
)}
export default Userlist;
So basically, react returns .map is not a function, and I assume it's because the array goes in empty. I'm fairly new to React, so if anyone could help me, I would greatly appreciate it. Thanks!
CodePudding user response:
I wouldn't name props for a component "props", really:
<Userlist props={userList}/>
If you really want to, then at least inside Userlist, you would need to refer to the props object:
props.props.map...
Name your props to something that make sense to you, like for example "users". Then call props.users.map(user => {...})
A React component can take many props. When you want to access them inside the component, you need to do so by name. In your case, you defined Userlist like this:
function Userlist(props){...}
In this case, all props would have to be accessed via the props object. You defined a props
value inside this object when you called <Userlist props={userList]} />
Personally, I always destructure props when I define a new component, like this:
function Userlist({users}) {...}
As a side note, your code would have worked if you had destructured the props object: function Userlist({props}) {...}
This would be the smallest change you could do to make the code work, I guess. But again, I would not use "props" as a name for a prop.
CodePudding user response:
The problem is that you are mapping over the props object, not the userList
.
Try to do the following:
const Userlist = (props) => {
return (
<div>
<div id='home-header'>
<h1>DevsHelp</h1>
</div>
<div id='userlist'>
// use props.users.map instead of props.map
{props.users.map((user) => {
return (
<div className='user'>
<h3>{user.username}</h3>
</div>
)
})}
</div>
</div>
)}
export default Userlist;
and at Home
component change the props of UserList to users
, just to avoid confusion
<Userlist users={userList}/>