[英]State not changing after update from use state
我是反应新手。 我正在尝试使我的套接字 io 监听器工作。 当我使用它时useEffect
可以工作,但它被调用了几次。 在useEffect
,它只被调用一次(这显然很好),但这次users
没有更新 - 初始值。
function Users() {
const [users, setUsers] = useState([]);
useEffect(() => {
getUsers();
if(users.length > 0) {
socket.on("statusChange", (data) => {
console.log(users); // this returns initial state of users
let tempUsers = [...users];
let ndx = tempUsers.findIndex(obj => obj.id === data.id);
if(ndx === -1)
return;
tempUsers[ndx].status = data.status;
setUsers(tempUsers);
});
}
}, []);
function getUsers() {
fetch(/* stuff */)
.then(res => res.json())
.then(res => setUsers(res.data));
}
return (
<div className={styles.container}>
<div className={styles.usersContainer}>
{ users.map((user, i) => <UserCard key={i} user={user} />) }
</div>
</div>
);
}
export default Users;
我做出假设的一些部分:
getUsers()
应该只被调用一次:当组件挂载时socket.on("statusChange")
并获取我们从getUsers()
获得的用户的更新。// This is pulled outside the component.
function getUsers() {
fetch(/* stuff */)
.then(res => res.json());
}
function Users() {
const [users, setUsers] = useState([]);
// Fetch users only once, when the component mounts.
useEffect(() => {
getUsers().then(res => {
setUsers(res.data);
});
}, []);
// Listen to changes
useEffect(() => {
if (!users.length) return;
const listener = (data) => {
// Functional update
// See: https://reactjs.org/docs/hooks-reference.html#functional-updates
setUsers(prevUsers => {
let nextUsers = [...prevUsers];
let ndx = nextUsers.findIndex(obj => obj.id === data.id);
// What's up here? See below.
if(ndx === -1) return nextUsers;
nextUsers[ndx].status = data.status;
return nextUsers;
});
};
socket.on("statusChange", listener);
// Unsubscribe when this component unmounts
// See: https://reactjs.org/docs/hooks-effect.html#example-using-hooks-1
return () => socket.off("details", listener);
}, [users]);
return (
<div className={styles.container}>
<div className={styles.usersContainer}>
{ users.map((user, i) => <UserCard key={i} user={user} />) }
</div>
</div>
);
}
export default Users;
关于if(ndx === -1) return nextUsers;
这意味着users
的大小永远不会改变,即您不会处理有关新用户的数据。
或者,您可以执行if(ndx === -1) return [...nextUsers, data ];
与其简单地执行 getUsers,不如将其与回调一起使用。 然后在callBack中执行setUsers:
function Users() { const [users, setUsers] = useState([]); useEffect(() => { fetch(/* stuff */).then(res => res.json()).then(res => { if(res.data.length > 0) { socket.on("statusChange", (data) => { console.log(res.data); // this returns initial state of users let tempUsers = [...res.data]; let ndx = tempUsers.findIndex(obj => obj.id === data.id); if(ndx === -1) return; tempUsers[ndx].status = data.status; setUsers(tempUsers); }); } }); }, []); return ( <div className={styles.container}> <div className={styles.usersContainer}> { users.map((user, i) => <UserCard key={i} user={user} />) } </div> </div> ); } export default Users;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.