我有两个useEffect-s。一种用于从api获取数据并将其保存为状态,另一种仅被调用一次,它开始侦听websocket事件。 在websocket事件处理程序中,我记录了获取的数据,但它始终具有默认值。 即使获取数据成功完成并且列表已在UI上绘制,列表的值始终为空-[]。
const [list, setList] = useState([]);
useEffect(() => {
axios.get("https://sample.api.com/get/list")
.then(res => {
setList(res.data);
});
}, [window.location.pathname.split('/')[2]]);
useEffect(() => {
webSocket.on('messageRecieved', (message) => {
console.log(list);
});
}, []);
答案 0 :(得分:1)
您的第二个效果是由于关闭而引用了初始列表值(一个空数组)。这就是为什么useEffect应该在其第二个参数中引用其所有依赖项。
但是在这种情况下,您不想每次更新列表时都订阅webSocket事件,则可以在列表上使用React的引用。
const listValue = useRef([]);
const [list, setList] = useState(listValue.current);
设置值时:
res => {
listValue.current = res.data
setList(listValue.current);
}
并且在一次触发的useEffect中检索列表时:
useEffect(() => {
webSocket.on('messageRecieved', (message) => {
console.log(listValue.current);
});
}, []);
答案 1 :(得分:0)
尝试更改
.then(res => {
到
.then((res) => {
请澄清是否向每个挂钩添加了控制台日志,或者说是否在其中预设置了值:
useEffect(() => {
axios.get("https://sample.api.com/get/list")
.then((res) => {
console.log(res.data)
setList(res.data);
});
}, [window.location.pathname.split('/')[2]]);
useEffect(() => {
webSocket.on('messageRecieved', (message) => {
console.log(list);
console.log(message);
});
}, []);
您还可以添加错误捕获,以防万一:
.catch((error) => {
console.log(error.response)
})