简体   繁体   English

state 的值始终是默认值。 反应 js 16.12.0

[英]value of state is always default. React js 16.12.0

I have two useEffect-s.我有两个 useEffect-s。 One is used to fetch data from api and save it in the state and second is called only once and it starts listening to websocket event.第一个用于从 api 获取数据并将其保存在状态中,第二个仅调用一次并开始侦听 websocket 事件。 In the websocket event handler I log the fetched data but it always has the default value.在 websocket 事件处理程序中,我记录了获取的数据,但它始终具有默认值。 Even though fetching data completes successfully and the list is drawn on UI, the value of list is always empty - [].即使获取数据成功完成并在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);
    }); 
}, []);

Your second effect is referencing the initial list value (an empty array) due to closure.由于关闭,您的第二个效果是引用初始列表值(一个空数组)。 This is why useEffect should reference all of its dependencies in its second argument.这就是 useEffect 应该在其第二个参数中引用其所有依赖项的原因。

But in this case, where you don't want to subscribe to the webSocket event each time the list is updated, you could use React's refs on the list.但是在这种情况下,您不想在每次更新列表时订阅 webSocket 事件,您可以在列表上使用 React 的 refs。

const listValue = useRef([]);
const [list, setList] = useState(listValue.current);

When setting the value:设置值时:

res => {
    listValue.current = res.data
    setList(listValue.current);
}

And when retrieving the list in a one time fired useEffect:并且在一次触发 useEffect 中检索列表时:

useEffect(() => {
    webSocket.on('messageRecieved', (message) => {
       console.log(listValue.current);
    }); 
}, []);

try changing尝试改变

.then(res => {

to

.then((res) => {

Would clarify if you added console logs to each hook or said if the values are preset in them:会澄清您是否向每个挂钩添加了控制台日志,或者说是否在其中预设了值:

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);
    }); 
}, []);

You could also add error catch, just in case:您还可以添加错误捕获,以防万一:

.catch((error) => {
    console.log(error.response)
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM