Javascript React Native:如何从子组件中的父组件访问变量?
我正在尝试将newsocket变量从MessagesScreen.js传递到ChatScreen.js 我已经在这一点上停留了一段时间,并将感谢任何可能的帮助。我试图实现的是,只发出一个连接,我可以监听两个屏幕上的事件 连接现在在messagesScreen上打开。我现在的问题是,如果用户1在allmessages屏幕上,而用户2在聊天室中。用户2向用户1发送消息,用户1的屏幕不会自动更新消息发送到的对话的最后一条消息,我需要滚动刷新或从一个页面导航到另一个页面才能显示 这是我的密码: 父-->messagesScreen.jsJavascript React Native:如何从子组件中的父组件访问变量?,javascript,react-native,socket.io,Javascript,React Native,Socket.io,我正在尝试将newsocket变量从MessagesScreen.js传递到ChatScreen.js 我已经在这一点上停留了一段时间,并将感谢任何可能的帮助。我试图实现的是,只发出一个连接,我可以监听两个屏幕上的事件 连接现在在messagesScreen上打开。我现在的问题是,如果用户1在allmessages屏幕上,而用户2在聊天室中。用户2向用户1发送消息,用户1的屏幕不会自动更新消息发送到的对话的最后一条消息,我需要滚动刷新或从一个页面导航到另一个页面才能显示 这是我的密码: 父-->
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
屏幕中传递变量并进行访问
MessagesScreen.js
routes.CHAT,{message:item,index,updateView, newsocket})}
const newsocket = route.params.newsocket;
....
newsocket.emit('subscribe', message.id); // call like this
chatScreen.js
routes.CHAT,{message:item,index,updateView, newsocket})}
const newsocket = route.params.newsocket;
....
newsocket.emit('subscribe', message.id); // call like this
我会以不同的方式来处理这个问题
您可以在单独的模块中将套接字连接创建为共享服务,并将其导入所需的相关组件中。在此共享模块中,您可以处理连接/断开连接并返回现有连接或创建新连接以返回
快速粗加工:
// 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;
//socket-server.ts
从“socket.io客户端”导入io;
let socket:SocketIOClient.socket=null;
export const getSocketServer=():Promise=>{
返回新承诺(解决=>{
中频(插座){
info(`返回现有套接字:${socket.id}`);
返回解析(套接字);
}
套接字=io('http://localhost:4000', {
自动连接:错误,
});
socket.on('connect_error',(err)=>{
控制台错误(err);
})
socket.on('connect',()=>{
info(`creatingnewsocket:${socket.id}`);
返回解析(套接字);
});
socket.open();
})
}
//然后在你的相关模块中
//模块a.ts
从“React”导入React,{useffect,useState};
从“/../components/socket server”导入{getSocketServer};
常量组件=()=>{
useffect(()=>{
const connect=async()=>{
const socket=wait getSocketServer();
socket.on('hello',(message)=>{
console.info(“模块A的你好”,消息);
});
}
connect();
}, []);
返回(
模块A
)
}
导出默认组件;
您还可以根据需要创建一个套接字并与相关模块共享该套接字
上下文提供了一种通过组件树传递数据的方法,而无需
必须在每一个关卡手动传递道具
嗨Mehran谢谢你回复我。在MessagesScreen inside中,当我console.log(newsocket)
获取套接字对象时,使用效果有效;但当我console.log(newsocket)
获取未定义的时,使用聊天屏幕。您也可以使用Redux。请通过这个@swand嗨,谢谢你回复我。有没有可能在没有redux的情况下实现这一点?请格式化代码以便于阅读。嗨,塞缪尔,谢谢你回复我。这不是我在socket.js顶部所做的吗?在这里,我在socket.js中创建连接,并将socket.js导入父组件。我有一个简单的问题:在我的父组件中的useffect
中,当我设置setSocket(newsocket)
时;如果我在之后尝试访问套接字状态变量(即,socket
),它是否也应该等于newsocket
?您希望能够在整个应用程序中共享此套接字服务-将其视为DB连接。这是一种典型的服务模式。任何时候状态改变或组件重新呈现变量:var socket
都将重新定义。如果您不完全了解状态如何更改以及组件如何重新渲染,请花点时间阅读。PS-在socket.js
中,您应该在开始发射之前确保连接。嗨,Samuel,我格式化了我的代码,使之更简单,并用我最近的更改对其进行了更新。当前,当我重新加载我的应用程序并转到父屏幕时,使用上面的代码,然后建立连接如果我离开此屏幕转到任何其他屏幕,然后返回,则连接仍然打开,不会关闭,然后再次打开。此外,my allMessages屏幕中的套接字侦听器当前正在侦听与聊天屏幕上相同的事件(send_message),这是否意味着我的套接字正在工作?是的,如果您在客户端上导航,它不应关闭和打开。如果确实希望它关闭,则对共享服务调用close方法。是的,所有注册侦听器的组件都将接收消息-这允许您在相关模块中以不同方式处理它们。