当函数中使用状态变量时,状态是未定义的



我有一个状态变量,我正在通过websocket更新。当记录变量以检查其状态时,它已正确更新,但是当我在函数中引用它以供使用时,它是未定义的。我是 React 和状态的新手,不确定我做错了什么。

在我使用${contactCalling}的两行上,它都显示为未定义。

任何帮助非常感谢!


import React from 'react';
import { useState, useEffect } from 'react';
import './App.css';
import socketIOClient from "socket.io-client";
import CallPane from './CallPane'
import '@opentok/client';
import {
    SERVER_BASE_URL,
} from './config';

const BASEURL = 'http://localhost:4001'
const socket = socketIOClient(BASEURL);
function App() {
    const [callFlag, setCallFlag] = useState(Boolean)
    const [apiData, setApiData] = useState([])
    const [contactCalling, setContactCalling] = useState('')
    console.log(contactCalling)
    socket.on("outgoing data", data => {
        console.log(data);
        setContactCalling(data.caller)
        alert(`${contactCalling} is calling you`)
        console.log('Call answered')
        setCallFlag(true);
    });
    useEffect ((contactCalling) => {
        fetch(SERVER_BASE_URL + `/room/${contactCalling}`)
            .then(data => data.json())
            .then(data => setApiData(data))
            .catch((err) => {
                console.error('Failed to get session credentials', err);
                alert('Failed to get opentok sessionId and token. Make sure you have updated the config.js file.');
            });
    },[])
    if (callFlag) {
        return (
            <div className="CallPane">
                <CallPane credentials={apiData}/>
            </div>
        );
    } else {
        return (
            <div className="CallPane">
            </div>
        );
    }
}
export default App;

我建议从基于类的组件而不是功能组件开始

创建一个内部包含状态对象的构造函数

并使用componentDidMount生命周期从套接字获取数据,并在组件正确挂载后使用setState函数将其保存到状态

componentDidMount生命周期将重新渲染 DOM,使其看起来像是初始渲染。如果获取速度很慢,您将看到它暂时空白,然后渲染到您需要的样子(它会渲染两次:一次在获取数据之前,一次在获取数据完成时,所以请记住,您可以在此处找到有关生命周期的更多信息 https://reactjs.org/docs/state-and-lifecycle.html(

您可以使用 Redux

从 websocket 进行获取并将其保存到 Redux 存储中,然后使用它更新您的组件

希望我的回答有所帮助

对于您的第一个 setContactCalling 调用,setContactCalling 是一个异步函数。像这样之后立即调用它并不能保证该值已更改(事实上,它很可能尚未更改(。但是,一旦状态发生变化,您可以依靠 react 再次渲染组件。只需使用组件中的值,而不是警报。也许改用模态。

对于 useImpact 内部的第二次调用,您正在尝试将 contactCalling 传递到函数中...但是该值是未定义的,因为 useEffect 不会向其传递任何内容。因此,它将注销为未定义。值 contactCalling 将通过 useEffect 回调之外的 setContactCalling 进行设置。与其像现在这样传递它,不如简单地将其添加到值数组中,以便 useEffect 像这样观看:

useEffect (() => {
    fetch(SERVER_BASE_URL + `/room/${contactCalling}`)
        .then(data => data.json())
        .then(data => setApiData(data))
        .catch((err) => {
            console.error('Failed to get session credentials', err);
            alert('Failed to get opentok sessionId and token. Make sure you have updated the config.js file.');
        });
},[contactCalling])

相关内容

  • 没有找到相关文章

最新更新