Hello I'm just new in React. I have a react component that shows list users. The data was from array of object. When I fetched new data that changed the properties in object the component was not re-render. How to solve that problem ?
Here's my code :
homepage.js
...
const [users, setUsers] = useState([])
async function connWS() {
ws.onmessage = async function(message) {
var parsedMessage = JSON.parse(message.data);
console.info('Received message: ' + message.data);
switch (parsedMessage.id) {
case 'updateListUser':
setUsers(parsedMessage.users);
break;
}
useEffect(() => {
async function init() {
await connWS();
}
init();
}, []);
return (
<Layout
isVideoCall={false}
rightSection={
<Users data={users} />
</Layout>
);
Users.js
const Users = ({data}) => {
return (
<div className={styled.users}>
{data.map((user) => (
<div className={styled.userItem}>
{user.imageUrl ? (
<img src={""} alt={user.name} />
) : (
<span style={{ backgroundColor: `#13c2c2` }}>
{user.shortName}
</span>
)}
<p>{user.name}</p>
{user.state ? (
user.state === 'REGISTERED' || 'registered' ? (
<p style={{ color: `#13c2c2` }}>Online</p>
) : (
<p style={{ color: `#f5222d` }}>Offline</p>
)
) : (
<p style={{ color: `#f5222d` }}>Offline</p>
)}
<div className={styled.overlay}>
<Button
className={styled.callBtn}
type="dashed"
size="large"
icon={
<Icon name="call" width={24} height={24} />
}
ghost
onClick={() => onClickCall(user.name)}
>
Call
</Button>
</div>
</div>
))}
</div>
);
};
}
Here's is the example of the users data look like.
const users = [
{
name: 'Josh',
state: 'registered'
},
{
name: 'Mike',
state: 'in_call'
}
]
I was trying to update the status users in list where they online/offline using websocket for realtime update. When I get the data from server that only change the state
properties, but the component is not re-render.
I was trying to resolve using different refference memory that create a new array of object using new data but i still didn't work.
As I look, you are correctly using the setUsers function provided by the useState hook to update the state. This should cause a re-render of the component, however, there are a few things you might want to check.
One final note is about your conditional rendering code for the user state. The condition user.state === 'REGISTERED' || 'registered' will always evaluate to true because 'registered' is a truthy value in JavaScript. You might want to change this to 'user.state==='REGISTERED' || user.state === 'registered' for the intended behavior.
Hope this answer would give you a hint.