【问题标题】:React State giving undefined, new to react反应状态给出未定义的新反应
【发布时间】:2021-03-05 13:37:17
【问题描述】:

我是 react-native 的新手,我一直在开发一个简单的应用程序,但由于某种原因,我的某些状态不断得到(未定义),而且在获取数据时,服务器被多次调用值( undefined) 在返回实际值之前。我已经搜索了很长时间,但没有找到任何有用的东西,所以我来这里寻求比我更高级的 React 开发人员的帮助。

我的代码如下所示:

const { data: chat, loading } = useApi(chatApi.getChat, { chatId: chatId, channelId: route.params.channelId });
const chatMessages = chat.messages  // I declared this only for testing
const [messages, setMessages] = useState(chatMessages);
console.log("Chat Messages: " + chatMessages)
console.log("messages State: " + messages)

在终端我得到:

Chat Messages: undefined
messages State: undefined
Chat Messages: undefined
messages State: undefined
Chat Messages: [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
messages State: undefined

另外,为什么在给出实际值之前,'chat' 变量会多次呈现值(未定义)?这导致后端WS服务器被多次调用而无缘无故导致性能变差

使用Api钩子:

import { useEffect, useState } from "react";

const useApi = (apiFunc, funcParams ={}) => {
    const [data, setData] = useState([]);
    const [error, setError] = useState(false);
    const [loading, setLoading] = useState(false);

    const fetchData = async () => {
        setLoading(true);
        const response = await apiFunc(funcParams);
        setLoading(false);
        if (!response.ok) return setError(true);
        setData(response.data);
    };
    useEffect(() => { fetchData() }, []);
    if (data) return { data, setData, error, loading, setLoading };
};

export default useApi;

完整代码

const chatId = route.params.chat.id;
    const { data: chat, loading } = useApi(chatApi.getChat, { chatId: chatId, channelId: route.params.channelId });
    const { user } = useAuth();
    const [text, setText] = useState(() => { return ""; });
    const chatMessages = chat.messages  // I declared this only for testing
    const [messages, setMessages] = useState(chatMessages);
    console.log("Chat Messages: " + chatMessages)
    console.log("messages State: " + messages)

    const chatSocket = new WebSocket(`${settings.wsUrl}chat/${chatId}/?userId=${user.id}`);
    

    // Join & Leave Room
    useEffect(() => {
        chatSocket.onmessage = e => {
            const data = JSON.parse(e.data);
            setMessages([...messages, data.message]);
        };
        return () => {
            chatSocket.close(0);
        };
    }, []);

    const handleSendMessage = () => {
        chatSocket.send(JSON.stringify({
            text: text,
        }));
        setText("");
    };

    return (
        <>
            ...
        </>

【问题讨论】:

    标签: javascript reactjs react-native websocket django-channels


    【解决方案1】:

    看起来您在加载数据时未定义(因为数据尚不存在,因此未定义),无论数据是否有,只要组件呈现,您就会打印变量的值尚未加载。

    您可以访问加载指示器:const { data: chat, loading },但您没有将加载变量用于任何有条件的操作。类似的东西

    if (!loading && data != null) {
       console.log("Chat Messages: " + chatMessages)
       console.log("messages State: " + messages)
       const chatSocket = new WebSocket(`${settings.wsUrl}chat/${chatId}/?userId=${user.id}`);
    }
    

    【讨论】:

    • 好的,这解决了多次渲染,但是为什么消息状态总是给出 undefined 而 chatMessages 变量给出一个值一次
    • useState 是一个 React 钩子,用于在渲染之间保留状态。这意味着您第一次渲染它时,您将它提供为chatMessages 作为输入(chatMessages 在第一次渲染时未定义,因为它尚未加载)。当组件重新渲染时,React 会记住 chatMessages 的状态(未定义)并且不会重置它。加载后,您需要调用 setMessages 。你可以通过几种方式做到这一点。在加载为依赖项的 onEffect 内部,或者您可以删除 useState 并将其作为变量(如果您不需要它作为状态)
    猜你喜欢
    • 1970-01-01
    • 2020-08-20
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    • 2021-09-18
    相关资源
    最近更新 更多