繁体   English   中英

React Native:如何从子组件中的父组件访问变量?

[英]React Native: How to access a variable from parent component in child component?

我正在尝试将我的 newsocket 变量从我的 MessagesScreen.js 传递给我的 ChatScreen.js。

我已经在这一点上停留了一段时间,并希望得到任何可能的帮助。 我想要实现的是只发出一个连接,我可以在两个屏幕上收听事件。

现在在messagesScreen 上打开了连接。 我现在的问题是,如果用户 1 在所有消息屏幕上,而用户 2 在聊天中。 用户 2 向用户 1 发送消息,用户 1 的屏幕不会自动更新消息发送到的对话的最后一条消息,我需要滚动刷新或从一个页面导航到另一个页面才能显示.

这是我的代码:

父 --> messagesScreen.js

function MessagesScreen({navigation}) {
const [posts, setPosts] = useState([]);
const { user } = useAuth();
const [socket, setSocket] = useState(null);

const loadposts = async () => {
const response = await messagesApi.getMessages();// here i am loading all the conversation this user has
setPosts(response.data)
};

useEffect(() => {

newsocket = sockets(user.id); // newsocket is what i am trying to pass to child component
setSocket(newsocket);

loadPosts()

newsocket.on("send_message", (msg) => {
  console.log("messages:", msg);
})

}, []);

return (
<FlatList
    data={posts}
    keyExtractor={(post) => post.id.toString()}
    renderItem={({ item,index }) => (
      <MessagesList
      title={item.Post.title}
        subTitle={item.Messages[0].message}
        onPress={() => navigation.navigate(
                routes.CHAT,{message:item,index,newsocket:socket})}
      />
    )}
  />
)

孩子--->chatScreen.js

function ChatScreen({route,navigation,socket}) {  
const [messages, setMessages] = useState([]);
const { user } = useAuth();

  const index = route.params.index;
  const message = route.params.message;
  const newsocket = route.params.newsocket;

  const loadListings = async () => {
  const response = await messagesApi.getConversation(message.id);// here i am loading the messages in that specific conversation
  setMessages(response.data.Messages)
  };

 useEffect(() => {
 loadListings()
 newsocket.emit('subscribe', message.id);

 newsocket.on("send_message", (msg) => {
    console.log("this is the chat messages:", msg);
    setMessages(messages => [msg, ...messages]);
  });
  }, []);

 const onSend = (ConversationId,senderId,receiverId,message) => {

const to = (user.id===route.params.message.user1? 
route.params.message.user2:route.params.message.user1)

socket.emit('message', { to: to, from: user.id, message,ConversationId});

messagesApi.sendMessage({ConversationId,senderId,receiverId,message});
};

return(
 <FlatList
    inverted
    data={messages}
    keyExtractor={(item,index)=>index.toString()}
    extraData={messages} // add this    
    renderItem={({item,index})=>(
        <MessageBubble
        text={item.message}
        mine={item.senderId !== user.id}
        />
    )}
    />
)

socket.js

import io from 'socket.io-client';

const newsocket = (user) => {
let newsocket = io.connect("http://192.168.1.107:9000")

newsocket.on('connect', msg => {
console.log(`waiting for user: ${user} to join a conversation`)
});

newsocket.emit('waiting', user);

return newsocket;
}

export default newsocket;

我会以不同的方式处理这个问题。

  1. 您可以在单独的模块中将套接字连接创建为共享服务,然后将其简单地导入所需的相关组件中。 在此共享模块中,您处理连接/断开连接并返回现有连接或创建新连接以返回。

快速粗略:

// socket-server.ts
import io from 'socket.io-client';

let socket: SocketIOClient.Socket = null;

export const getSocketServer = (): Promise<SocketIOClient.Socket> => {
    return new Promise<SocketIOClient.Socket>(resolve => {
        if (socket) {
            console.info(`returning existing socket: ${socket.id}`);

            return resolve(socket);
        }

        socket = io('http://localhost:4000', {
            autoConnect: false,
        });

        socket.on('connect_error', (err) => {
            console.error(err);
        })

        socket.on('connect', () => {
            console.info(`creating new socket: ${socket.id}`);

            return resolve(socket);
        });

        socket.open();
    })
}

// then in your relevant modules
// module-a.ts
import React, {useEffect, useState} from 'react';
import {getSocketServer} from './../components/socket-server';

const Component = () => {
    useEffect(() => {
        const connect = async () => {
            const socket = await getSocketServer();

            socket.on('hello', (message) => {
                console.info('hello from module A', message);
            });
        }
        connect();
    }, []);

    return (
        <>
            <h2>Module A</h2>
        </>
    )
}

export default Component;
  1. 您也许还可以查看创建上下文提供程序并根据需要与相关模块共享套接字。

Context 提供了一种通过组件树传递数据的方法,而无需在每个级别手动传递 props。

MessagesScreen屏幕上,您传递的是SOCKET function 而不是它本身的变量。 我认为你不需要 function。 您直接传递变量并在chatScreen屏幕中访问。

MessagesScreen.js

routes.CHAT,{message:item,index,updateView, newsocket})}

聊天屏幕.js

const newsocket = route.params.newsocket;
 ....

newsocket.emit('subscribe', message.id);  // call like this

暂无
暂无

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

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