简体   繁体   English

当传递到组件的道具时,反应钩子数组传递数字

[英]React hooks array passing in number when passed into props of component

I am currently working on a chat application and for some reason every time I pass in my array of messages as a prop to another component it passes in a number to the component instead of the message object.我目前正在开发一个聊天应用程序,由于某种原因,每次我将我的消息数组作为道具传递给另一个组件时,它都会将一个数字传递给该组件,而不是消息 object。 I have tried a lot of different methods of passing it in regarding using multiple components etc but it seems to still be passing in the number of elements for some reason.关于使用多个组件等,我尝试了很多不同的方法来传递它,但由于某种原因,它似乎仍在传递元素的数量。 Any help is appreciated... code is below任何帮助表示赞赏...代码如下

Component receiving the props接收道具的组件

import React, { useEffect } from 'react'
import Message from '../../Message/Message'

function Messages({ messages }) {
    useEffect(() => {
        console.log(messages)
    }, [messages])
    return (
        <div>
            test
        </div>
    )
}

export default Messages
// Import React dependencies.
import React, { useEffect, useState, } from "react";
// Import React dependencies.
import io from 'socket.io-client'
import axios from 'axios'
import Messages from './Messages/Messages'
import uuid from 'react-uuid'
import { Redirect } from 'react-router-dom'
// Import the Slate components and React plugin.
const ENDPOINT = 'http://localhost:5000/'
export const socket = io.connect(ENDPOINT)




const LiveChatFunction = ({ group_id }) => {
    // Add the initial value when setting up our state.
    const [message, setValue] = useState("")
    const [user, setUser] = useState("")
    const [groupId, setGroup] = useState('')
    const [messages, setMessages] = useState([])
    const [toLogin, userAuth] = useState(false)
    useEffect(() => {

        setGroup(group_id)
        axios.post('http://localhost:5000/api/users/refresh_token', null, { withCredentials: true }).then(data => {
            if (!data.data.accessToken) {
                userAuth(true)
            }
        })
        axios.get('http://localhost:5000/api/users/userInfo', { withCredentials: true }).then(data => {
            setUser(data.data.user)
        })
        socket.on(`message-${group_id}`, data => {
            setMessages(messages.push(data))
        });

        axios.get(`http://localhost:5000/live/${group_id}`).then(x => {
            console.log(x.data)
        })
    }, [group_id, messages])

    function setClick() {
        const data = {
            messageId: uuid(),
            user,
            groupId,
            message
        }
        socket.emit('message', data)
    }

    if (toLogin) {
        return (
            <Redirect to="/login" />
        )
    }
    return (
        <div>
            <input placeholder="message" type="text" onChange={value => {
                setValue(value.target.value)
                socket.emit('typing-message', { username: user, time: new Date() })
            }} />
            <button onClick={setClick}>Submit</button>
            <Messages messages={messages} />
        </div>

    )
}

export default LiveChatFunction;

I have added some comments of what I think you can change:我添加了一些我认为您可以更改的评论:

useEffect(() => {
  const recieveFunction = (data) => {
    //using callback so no dependency on messages
    setMessages((messages) => messages.push(data));
  };
  async function init() {
    //next line is pointless, this runs when group_id
    // has changed so something must have set it
    // setGroup(group_id);
    await axios //not sure if this should be done before listening to socket
      .post(
        'http://localhost:5000/api/users/refresh_token',
        null,
        { withCredentials: true }
      )
      .then((data) => {
        if (!data.data.accessToken) {
          userAuth(true);
        }
      });
    await axios
      .get('http://localhost:5000/api/users/userInfo', {
        withCredentials: true,
      })
      .then((data) => {
        setUser(data.data.user);
      });
    //start listening to socket after user info is set
    socket.on(`message-${group_id}`, recieveFunction);

    axios
      .get(`http://localhost:5000/live/${group_id}`)
      .then((x) => {
        console.log(x.data);
      });
  }
  init();
  //returning cleanup function, guessing socket.off exists
  return () =>
    socket.off(`message-${group_id}`, recieveFunction);
}, [group_id]); //no messages dependencies
console.log('messages are now:',messages);

If messages is still not set correctly then can you log it如果消息仍然没有正确设置,那么你可以记录它吗

So I think I found your problem:所以我想我发现了你的问题:

In your useEffect hook, you're setting messages to the wrong thing.在您的useEffect挂钩中,您将消息设置为错误的内容。

socket.on(`message-${group_id}`, data => {
    setMessages(messages.push(data))
});

An example:一个例子:

const m = [].push();
console.log(m);
// m === 0
const n = [].push({});
console.log(n);
// n === 1

As you can see this is the index.如您所见,这是索引。

So what you need is:所以你需要的是:

socket.on(`message-${group_id}`, data => {
    messages.push(data);
    setMessages(messages);
});

This will set messages to the array of messages.这会将消息设置为消息数组。

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

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