如何在另一个函数中使用在 useEffect() 中声明的变量?
How to use variable declared in useEffect() in another function?
p.s 解决了我遇到的问题,但如果您有时间,我仍然想听听您对此和我的代码的看法:)
我只能在渲染完成后为该变量赋值,所以我假设我必须在 useEffect() 中声明该变量,并且不可能在全局范围内为其赋值(执行在任何渲染之前)。但我也想在另一个 useEffect() 中使用该变量,但我不能,因为它是在函数内部声明的,它不属于全局范围。
另外,有两个 useEffect -s 是否正常?我需要获取 canvas 的上下文并保持该上下文一致(不是在每次 DOM 更新时获取新的上下文,因为当我不将 [] 作为第一个 useEffect 的第二个参数时会发生这种情况).另一个是随着状态的变化在独特的上下文中做事。是否有意义?我的代码:
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;
是的,当它们在第二个参数中有不同的参数时,有多个 useEffect 是有意义的。
您可以将 useEffec 之外的变量声明为未定义。
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
属性 中。否则最好放在useEffect
.
里面
p.s 解决了我遇到的问题,但如果您有时间,我仍然想听听您对此和我的代码的看法:)
我只能在渲染完成后为该变量赋值,所以我假设我必须在 useEffect() 中声明该变量,并且不可能在全局范围内为其赋值(执行在任何渲染之前)。但我也想在另一个 useEffect() 中使用该变量,但我不能,因为它是在函数内部声明的,它不属于全局范围。 另外,有两个 useEffect -s 是否正常?我需要获取 canvas 的上下文并保持该上下文一致(不是在每次 DOM 更新时获取新的上下文,因为当我不将 [] 作为第一个 useEffect 的第二个参数时会发生这种情况).另一个是随着状态的变化在独特的上下文中做事。是否有意义?我的代码:
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;
是的,当它们在第二个参数中有不同的参数时,有多个 useEffect 是有意义的。
您可以将 useEffec 之外的变量声明为未定义。
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
属性 中。否则最好放在useEffect
.