Reactjs 使用带有React-useEffect挂钩的侦听器
我有一个useEffect挂钩,可以在我的应用程序中处理在线用户Reactjs 使用带有React-useEffect挂钩的侦听器,reactjs,react-native,react-hooks,Reactjs,React Native,React Hooks,我有一个useEffect挂钩,可以在我的应用程序中处理在线用户 const [users, setUsers] = useState({} as Users); useEffect(() => { const handleOnlineStatus = (onlineStatus: Array<OnlineStatus>) => { const usersCopy = {...users}; if (onlineStatus.length ===
const [users, setUsers] = useState({} as Users);
useEffect(() => {
const handleOnlineStatus = (onlineStatus: Array<OnlineStatus>) => {
const usersCopy = {...users};
if (onlineStatus.length === 0) {
return;
}
onlineStatus.forEach((status: OnlineStatus) => {
const uid = status.userId;
if (!uid) {
return;
}
if (uid in usersCopy) {
const lastStatus = usersCopy[uid].status;
if (lastStatus !== usersCopy) {
usersCopy[uid].status = status.value;
setUsers({...usersCopy});
}
}
});
};
subscribeToIsOnline((onlineStatus: Array<OnlineStatus>) => {
handleOnlineStatus(onlineStatus);
});
});
public handleOnlineStatus(callback: (users: Array<OnlineStatus>) => void) {
this.logDebug('subscribeToOnlineStatusIndication');
try {
return ChatClient.addListener('OnlineStatusIndication', (users: Array<OnlineStatus>) => callback(users));
} catch (e) {
this.logError(e);
}
}
const[users,setUsers]=useState({}作为用户);
useffect(()=>{
const handleOnlineStatus=(onlineStatus:Array)=>{
const usersCopy={…users};
如果(onlineStatus.length==0){
返回;
}
onlineStatus.forEach((状态:onlineStatus)=>{
const uid=status.userId;
如果(!uid){
返回;
}
if(userscope中的uid){
const lastStatus=UserScope[uid]。状态;
if(lastStatus!==用户状态){
UserScope[uid]。状态=状态。值;
setUsers({…usersCopy});
}
}
});
};
subscribeToIsOnline((onlineStatus:Array)=>{
HandlineStatus(联机状态);
});
});
公共handleOnlineStatus(回调:(用户:数组)=>void){
this.logDebug('subscribeToOnlineStatusIndication');
试一试{
返回ChatClient.addListener('OnlineStatusIndication',(用户:数组)=>回调(用户));
}捕获(e){
这是logError(e);
}
}
但使用此代码,每次用户重新联机时都会重新创建侦听器。
所以我更新了代码如下:
useEffect(() => {
// ... same code
}, []); // <--
useffect(()=>{
//…相同的代码
}, []); // 我认为您的思路是正确的,但是您已经在回调中包含了初始的用户
状态对象({}
)。换句话说,它是一个过时的存储模块,因此您总是从初始渲染复制用户
状态
您还使用usersCopy[uid]改变状态代码>
使用功能状态更新访问您可以从中进行更新的上一个状态
const [users, setUsers] = useState({} as Users);
useEffect(() => {
const handleOnlineStatus = (onlineStatus: Array<OnlineStatus>) => {
if (!onlineStatus.length) {
return;
}
onlineStatus.forEach((status: OnlineStatus) => {
const uid = status.userId;
if (!uid) {
return;
}
setUsers(users => {
if (uid in users) {
const lastStatus = users[uid].status;
if (lastStatus !== users) {
return {
...users, // <-- shallow copy into new state object
[uid]: {
...users[uid], // <-- shallow copy old user object
status: status.value, // <-- update property
}
};
}
}
return users; // <-- old state
});
});
};
subscribeToIsOnline((onlineStatus: Array<OnlineStatus>) => {
handleOnlineStatus(onlineStatus);
});
}, []); // <-- empty dependency array to run effect once
const[users,setUsers]=useState({}作为用户);
useffect(()=>{
const handleOnlineStatus=(onlineStatus:Array)=>{
如果(!onlineStatus.length){
返回;
}
onlineStatus.forEach((状态:onlineStatus)=>{
const uid=status.userId;
如果(!uid){
返回;
}
设置用户(用户=>{
如果(用户中的uid){
const lastStatus=用户[uid]。状态;
if(lastStatus!==用户){
返回{
…用户,//subscribeToIsOnline
是否返回一些清理功能,如unsubscribe
?不,这是一个简单的addListener,我更新了codeAh bummer,如果它更新了会更容易。我们必须解决这个问题。也许我可以尝试添加一个,ChatClient是我们的代码。为什么它很重要?订阅者应该只实例化一次对吗?好吧,你的用户
状态有一个陈旧的外壳,如果subscribeToIsOnline
返回了一个清理函数,你可以简单地使用用户
作为使用效果
依赖项,并在用户
状态更新时返回清理函数删除侦听器。另一种方法包括它将处理程序拆分为自己的记忆回调或重写逻辑,以便使用功能状态更新。UserScope中的uid
检查有点搞砸了。谢谢Drew。您的代码正在工作,最重要的是我了解发生了什么!