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

时间:2019-09-27 18:47:39

标签: reactjs canvas react-hooks use-effect react-canvas

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

我只能在渲染完成后才给该变量赋值,所以我假设我必须在useEffect()中声明该变量,并且不可能在全局范围内给它赋值(在执行任何操作之前先执行)呈现)。但是我也想在另一个useEffect()中使用该变量,但是我不能,因为它是在函数内部声明的,并且不属于全局范围。 另外,有两个useEffect -s是否正常?我需要获取画布的上下文并保持该上下文的一致性(不要在每次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;

2 个答案:

答案 0 :(得分:2)

是的,当第二个参数中的参数与您一样时,使用倍数useEffect是有意义的。

您可以将useEffec外部的变量声明为undefined。

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]);

这种方法在功能范围内可用

答案 1 :(得分:1)

如果你在 useEffect 之外声明变量,它会在每次渲染后丢失任何赋值。

更好的方法是使用 useRef 钩子并将可变值保留在 .current 属性中。否则,最好将其保存在 useEffect 内。