Reactjs 如何在另一个函数中使用useffect()中声明的变量?

Reactjs 如何在另一个函数中使用useffect()中声明的变量?,reactjs,canvas,react-hooks,use-effect,react-canvas,Reactjs,Canvas,React Hooks,Use Effect,React Canvas,p、 s解决了我遇到的问题,但如果您有时间,我仍然希望听听您对此和我的代码的想法:) 我只能在渲染完成后为该变量赋值,所以我假设我必须在useffect()中声明该变量,并且不可能在全局范围(在任何渲染之前执行)中为其赋值。但我也想在另一个useffect()中使用该变量,但我不能,因为它是在函数中声明的,不属于全局范围。 另外,有两个useffect-s是正常的吗?我需要一个抓取canvas上下文并保持上下文一致(不是每次DOM更新都抓取新的上下文,因为我没有将[]作为第一个useffect的

p、 s解决了我遇到的问题,但如果您有时间,我仍然希望听听您对此和我的代码的想法:)

我只能在渲染完成后为该变量赋值,所以我假设我必须在useffect()中声明该变量,并且不可能在全局范围(在任何渲染之前执行)中为其赋值。但我也想在另一个useffect()中使用该变量,但我不能,因为它是在函数中声明的,不属于全局范围。 另外,有两个useffect-s是正常的吗?我需要一个抓取canvas上下文并保持上下文一致(不是每次DOM更新都抓取新的上下文,因为我没有将[]作为第一个useffect的第二个参数)。另一个是在状态发生变化时,利用这种独特的环境进行操作。这有意义吗?我的代码:

import React, { useState, useRef, useEffect } from "react";
import { degreesToRadiansFlipped } from "./helpers/degreesToRadiansFlipped";
function Circle() {
  let [degree, setDegree] = useState(0);
  const canvas = useRef();
  const inputField = useRef();
  const coordinateX = Math.cos(degreesToRadiansFlipped(degree)) * 100 + 250;
  const coordinateY = Math.sin(degreesToRadiansFlipped(degree)) * 100 + 250;

  useEffect(() => {
    const context = canvas.current.getContext("2d");
    drawCircle(context, coordinateX, coordinateY);
    return context;
    /*return function cleanUp() {
      context.clearRect(0, 0, 500, 500);
      context.beginPath();
      drawCircle(context, coordinateX, coordinateY);
    };*/
  }, []);
  useEffect(() => {
    drawCircle(context, coordinateX, coordinateY);
  }, [degree]);
  let drawCircle = function(context, x, y) {
    context.beginPath();
    //arc has option to make it anti-clockwise, making flipping radians redundant
    context.arc(250, 250, 100, 0, Math.PI * 2);
    context.moveTo(250, 250);
    context.lineTo(x, y);
    context.stroke();
  };

  return (
    <div>
      <canvas ref={canvas} width={500} height={500}></canvas>
      <form
        onSubmit={(e) => {
          e.preventDefault();
          setDegree(inputField.current.value);
        }}
      >
        <input type="text" ref={inputField}></input>
        <button type="submit">Submit</button>
      </form>
    </div>
  );
}

export default Circle;
import React,{useState,useRef,useffect}来自“React”;
从“/helpers/degreestorarisflipped”导入{degreestorarisflipped};
函数圆(){
let[degree,setDegree]=useState(0);
const canvas=useRef();
const inputField=useRef();
常数坐标=Math.cos(degreesToRadiansFlipped(degree))*100+250;
const coordinateY=数学sin(degreesToRadiansFlipped(degree))*100+250;
useffect(()=>{
const context=canvas.current.getContext(“2d”);
画圈(上下文、坐标、坐标);
返回上下文;
/*返回函数cleanUp(){
clearRect(0,0500500);
context.beginPath();
画圈(上下文、坐标、坐标);
};*/
}, []);
useffect(()=>{
画圈(上下文、坐标、坐标);
},[学位];
设drawCircle=函数(上下文,x,y){
context.beginPath();
//arc可以选择使其逆时针旋转,从而使翻转弧度变得多余
弧(250250100,0,Math.PI*2);
上下文。移动到(250250);
lineTo(x,y);
stroke();
};
返回(
{
e、 预防默认值();
设置度(inputField.current.value);
}}
>
提交
);
}
导出默认圆;

是,当第二个参数中的参数与您所做的不同时,使用multiples useffect是有意义的

您可以将useeffic之外的变量声明为未定义

let context = undefined // is not constant
  useEffect(() => {
    context = canvas.current.getContext("2d");
    drawCircle(context, coordinateX, coordinateY);
    return context;
    /*return function cleanUp() {
      context.clearRect(0, 0, 500, 500);
      context.beginPath();
      drawCircle(context, coordinateX, coordinateY);
    };*/
  }, []);
  useEffect(() => {
    drawCircle(context, coordinateX, coordinateY);
  }, [degree]);

这种方法在函数范围中可用

我知道这是一个旧线程,但万一有人遇到这种情况。如果在useEffect之外声明变量,则每次渲染后它将丢失任何赋值。更好的方法是使用useRef钩子并将可变值保留在.current属性中。否则,最好将其保持在有效范围内