gpt4 book ai didi

reactjs - useEffect 中的状态总是指 React Hooks 的初始状态

转载 作者:行者123 更新时间:2023-12-03 13:23:39 25 4
gpt4 key购买 nike

每次我从另一个组件发出消息时,我都无法获取完整的消息列表。这是钩子(Hook)和 View 组件:

export function useChat() {
const [messages, setMessages] = useState([]);

useEffect(() => {
const socket = openSocket("http://localhost:3003");
socket.on("chat message", msg => {
const newState = update(messages, { $push: [msg] });
setMessages(newState);
});
}, []);

return { messages };
}

不幸的是,该状态不会持续存在,并且始终显示最后一条消息:

export const HookSockets = () => {
const { messages } = useChat();
return (
<div>
{messages.map((message, index) => (
<div key={index}>{message}</div>
))}
</div>
);
};

如果我按照常规方式执行此操作,一切都会按预期进行:

export class ClassSockets extends Component {
state = {
socket: openSocket("http://localhost:3003"),
messages: [],
message: ""
};

componentDidMount() {
this.state.socket.on("chat message", msg => {
const newState = update(this.state, {
messages: { $push: [msg] }
});
this.setState(newState);
});
}

handleClick = () => {
this.state.socket.emit("chat message", this.state.message);
this.setState({ message: "" });
};

handleChange = event => {
this.setState({ message: event.target.value });
};

render() {
return (
<div>
<div>Sockets</div>
<div>{this.state.messages}</div>
<input
type="text"
value={this.state.message}
onChange={this.handleChange}
/>
<button onClick={this.handleClick}>Send Message</button>
</div>
);
}
}

最佳答案

由于您已将 useEffect 编写为在组件初始安装时执行,因此它会创建一个引用 messages 初始值的闭包,即使消息更新,它仍然会引用相同的值在后续调用中

您应该将 useEffect 配置为在初始安装和消息更改时运行

export function useChat() {
const [messages, setMessages] = useState([]);

useEffect(() => {
const socket = openSocket("http://localhost:3003");
socket.on("chat message", msg => {
const newState = update(messages, { $push: [msg] });
setMessages(newState);
});
}, [messages]);

return { messages };
}

否则你可以使用回调模式来更新状态

export function useChat() {
const [messages, setMessages] = useState([]);

useEffect(() => {
const socket = openSocket("http://localhost:3003");
socket.on("chat message", msg => {
setMessages(prevMessages => update(prevMessages, { $push: [msg] }););
});
}, []);

return { messages };
}

关于reactjs - useEffect 中的状态总是指 React Hooks 的初始状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54675523/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com