Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript作用域和函数_Javascript_Reactjs_Socket.io_Use Effect - Fatal编程技术网

Javascript作用域和函数

Javascript作用域和函数,javascript,reactjs,socket.io,use-effect,Javascript,Reactjs,Socket.io,Use Effect,我知道函数在Javascript中是如何闭包的,以及它们如何访问父作用域中声明的变量。在这里,我在一个功能组件中定义了一个名为socket的变量 function someName() { const ENDPOINT = "localhost:5000"; let socket useEffect(() => { socket = io(ENDPOINT) // and some code }, [])

我知道函数在Javascript中是如何闭包的,以及它们如何访问父作用域中声明的变量。在这里,我在一个功能组件中定义了一个名为socket的变量

function someName() {
    const ENDPOINT = "localhost:5000";
    let socket

    useEffect(() => {
          socket = io(ENDPOINT)
      // and some code
    }, [])

   const handleClick = () => {
         socket.emit('someEvent', someMessage)  // error: cannot read property emit of undefined
         }
   }

   return (
        <input />
        <button onClick={handleClick}
         )
函数someName(){
const ENDPOINT=“localhost:5000”;
插座
useffect(()=>{
套接字=io(端点)
//还有一些代码
}, [])
常量handleClick=()=>{
emit('someEvent',someMessage)//错误:无法读取未定义的属性emit
}
}
返回(

useffect
每次依赖项更改时都会运行。在您的情况下,依赖项是
[]
,这意味着它永远不会更改,这意味着useffect永远不会运行多次

因此,每次组件重新渲染时,都会创建一个新的
socket
变量,因为
useffect
不会再次运行,所以该变量保持
未定义

您需要做的是确保在每次重新渲染时返回相同的
socket
。最简单和推荐的方法是使用
useRef
钩子确保在每次重新渲染时返回相同的值引用

您的代码应该如下所示:

import React, { useEffect, useRef } from 'react';
import io from 'something';

function someName() {
  const ENDPOINT = "localhost:5000";
  const socket = useRef(null);

  useEffect(() => {
    socket.current = io(ENDPOINT);
    // and some code
  }, [])

  const handleClick = () => {
    socket.current.emit('someEvent', someMessage);
  };

  return (
    <>
      <input />
      <button onClick={handleClick}
    </>
  );
}
import React,{useffect,useRef}来自“React”;
从“某物”导入io;
函数someName(){
const ENDPOINT=“localhost:5000”;
const socket=useRef(null);
useffect(()=>{
socket.current=io(端点);
//还有一些代码
}, [])
常量handleClick=()=>{
socket.current.emit('someEvent',someMessage);
};
返回(

useffect
每次依赖项更改时都会运行。在您的情况下,依赖项是
[]
,这意味着它永远不会更改,这意味着useffect永远不会运行多次

因此,每次组件重新渲染时,都会创建一个新的
socket
变量,因为
useffect
不会再次运行,所以该变量保持
未定义

您需要做的是确保在每次重新渲染时返回相同的
socket
。最简单和推荐的方法是使用
useRef
钩子确保在每次重新渲染时返回相同的值引用

您的代码应该如下所示:

import React, { useEffect, useRef } from 'react';
import io from 'something';

function someName() {
  const ENDPOINT = "localhost:5000";
  const socket = useRef(null);

  useEffect(() => {
    socket.current = io(ENDPOINT);
    // and some code
  }, [])

  const handleClick = () => {
    socket.current.emit('someEvent', someMessage);
  };

  return (
    <>
      <input />
      <button onClick={handleClick}
    </>
  );
}
import React,{useffect,useRef}来自“React”;
从“某物”导入io;
函数someName(){
const ENDPOINT=“localhost:5000”;
const socket=useRef(null);
useffect(()=>{
socket.current=io(端点);
//还有一些代码
}, [])
常量handleClick=()=>{
socket.current.emit('someEvent',someMessage);
};
返回(

这里的问题是,在下一次渲染时(在装载回调之后),
socket
值被重新定义,其值是
未定义的

可能的解决方案如下:

import React, { useEffect } from "react";
import io from "socket.io";

const ENDPOINT = "...";
let socket = io(ENDPOINT);

function Component() {
  const handleClick = () => {
    socket.emit("someEvent", "some message");
  };

  return (
    <>
      <input />
      <button onClick={handleClick} />
    </>
  );
}
import React,{useffect}来自“React”;
从“socket.io”导入io;
const ENDPOINT=“…”;
让套接字=io(端点);
函数组件(){
常量handleClick=()=>{
发出(“someEvent”、“somemessage”);
};
返回(
);
}

请注意,
socket.io
应该有一个实例(全局变量/singleton),这样的实例应该在其他文件中公开(导出它),然后每个组件都应该通过修改实例来独立使用它。

这里的问题是在下一次渲染时(在装载回调之后),
套接字
值被重新定义,其值为
未定义

可能的解决方案如下:

import React, { useEffect } from "react";
import io from "socket.io";

const ENDPOINT = "...";
let socket = io(ENDPOINT);

function Component() {
  const handleClick = () => {
    socket.emit("someEvent", "some message");
  };

  return (
    <>
      <input />
      <button onClick={handleClick} />
    </>
  );
}
import React,{useffect}来自“React”;
从“socket.io”导入io;
const ENDPOINT=“…”;
让套接字=io(端点);
函数组件(){
常量handleClick=()=>{
发出(“someEvent”、“somemessage”);
};
返回(
);
}


请注意,
socket.io
应该有一个实例(全局变量/singleton),这样的实例应该在其他文件中公开(导出它),然后每个组件都应该通过修改实例来独立使用它。

我不认为问题出在使用
useEeffect
上。您确定使用的是
io(端点)吗
正确吗?您可以看一看。@nibble不幸的是,它是错误的。套接字将在此处未定义。您需要使用一个ref来存储您的套接字id。
io
返回什么?@Yousaf它是socket.io,如他的标记中所述。我认为问题不在于您使用的
useEeffect
是否确实使用了de>io(端点)
正确吗?您可以看一看。@nibble不幸的是,它是错误的。套接字将在此处未定义。您需要使用一个ref来存储您的套接字id。
io
返回什么?@Yousaf如果它是socket.io,如他的标记中所述。单击按钮时,
socket.current
be
undefined
。@evolutionxbox是的,当然,但这种情况不会发生在真正使用应用程序的人身上,因为
useffect
将在页面呈现后立即运行。套接字可能会失败?不确定为什么会被否决,如果这是正确的位置,套接字初始化不是OP所要求的。@evolutionxbox我应该看护吗OP解决了所有这些问题?可能是
socket。当点击按钮时,当前的
可能是
未定义的
。@evolutionxbox肯定是的,但这种情况不会发生在真正使用应用程序的人身上,因为
useffect
会在页面呈现后立即运行。socket可能会失败?不确定是什么y这是被否决的,如果这是正确的位置,socket init不是OP所要求的。@evolutionxbox我应该通过所有这些问题来照顾OP吗?为什么在组件外部定义变量会有帮助?如果在上呈现多个
组件
s会发生什么