Как использовать переменную, объявленную в useEffect (), в другой функции?

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;

person Irakli Tchigladze    schedule 27.09.2019    source источник


Ответы (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]);

этот способ доступен в области действия функции

person Ariel Batista    schedule 27.09.2019

Если вы объявляете переменную вне useEffect, она теряет все присвоения после каждого рендеринга.

Лучше использовать ловушку useRef и сохранить изменяемое значение в свойстве .current. В противном случае лучше оставить его внутри useEffect.

person pepperRodney    schedule 18.06.2021