ReactJS отправка ссылки в глобальное состояние useContext (Konva) - PullRequest
0 голосов
/ 27 апреля 2020

Я использую useContext в качестве решения для глобального состояния. У меня есть Store.jsx, который содержит мое состояние, и reducer.jsx, который уменьшает. Я использую Konva для создания фигур на холсте HTML5. Моя цель - когда я нажимаю на форму, я хочу обновить свое глобальное состояние со ссылкой на то, что активно, и когда я нажимаю снова, чтобы очистить ссылку.

Мой полный код можно найти здесь: https://codesandbox.io/s/staging-platform-2li83?file= / src / App.jsx

Проблема:

проблема в том, что когда я обновляю глобальное состояние через событие onClick формы, он говорит, что ссылка 'null', но когда я console.log ссылка в onClick, я вижу правильную ссылку.

Я думаю, что упускаю важный момент, как работает useRef.

Вот как выглядит поток в моей голове, когда я думаю об этом:

Я создаю холст и сопоставляю массив свойств прямоугольника. Это создает 4 прямоугольника. Я использую компонент-оболочку, которая возвращает прямоугольник.

          {rectArray.map((rectangle, index) => {
            return (
              <RectWrapper key={index} rectangle={rectangle} index={index} />
            );
          })}

Внутри RectWrapper я создаю ссылку и передаю ее в опорный пункт Rect. В функции onclick, когда я консоль журнала 'shapeRef', я вижу ссылку только тогда, когда отправка закомментирована. Если я раскомментирую рассылку, то она будет отображаться как ноль, а если я утешу лог-состояние, ссылка всегда будет нулевой.

const RectWrapper = ({ rectangle, index }) => {
    const shapeRef = React.useRef();

    return (
      <Rect
        x={rectangle.x + index * 100}
        y={5}
        width={50}
        height={50}
        fill="red"
        ref={shapeRef}
        onClick={() => {
          console.log("ShapeRef: ");
          console.log(shapeRef); // This correctly identifies the rect only when dispatch is uncommented
          dispatch({
            type: "active_image",
            payload: {
              index: index,
              reference: shapeRef
            }
          });
        }}
      />
    );
  };

возможно, я ошибаюсь с помощью ловушек. Я просто пытаюсь сохранить общее состояние того, на что нажали, потому что компоненты в другом файле будут полагаться на это состояние.

Ответы [ 2 ]

1 голос
/ 27 апреля 2020

Проблема возникает из-за того, что вы создаете компонент RectWrapper в качестве функционального компонента в компоненте приложения, вызывая повторное создание новой ссылки на компонент и, таким образом, ссылка теряется

Переместите RectWrapper в отдельный компонент, объявленный вне компонента App и передаваемый ему dispatch в качестве опоры

import React, { useEffect, useContext, useState, Component } from "react";
import { Stage, Layer, Rect, Transformer } from "react-konva";
import { Context } from "./Store.jsx";
import "./styles.css";

const RectWrapper = ({ rectangle, index, dispatch }) => {
  const shapeRef = React.useRef();

  return (
    <Rect
      x={rectangle.x + index * 100}
      y={5}
      width={50}
      height={50}
      fill="red"
      ref={shapeRef}
      onClick={() => {
        console.log("ShapeRef: ");
        console.log(shapeRef); 
        dispatch({
          type: "active_image",
          payload: {
            index: index,
            reference: shapeRef
          }
        });
      }}
    />
  );
};

export default function App() {
  const [state, dispatch] = useContext(Context);

  console.log("Global State:");
  console.log(state);

  const rectArray = [
    { x: 10, y: 10 },
    { x: 10, y: 10 },
    { x: 10, y: 10 },
    { x: 10, y: 10 }
  ];

  return (
    <div className="App">
      <Stage height={500} width={500}>
        <Layer>
          {rectArray.map((rectangle, index) => {
            return (
              <RectWrapper
                dispatch={dispatch}
                key={index}
                rectangle={rectangle}
                index={index}
              />
            );
          })}
        </Layer>
      </Stage>
    </div>
  );
}

Рабочая демонстрация

0 голосов
/ 27 апреля 2020

Не думаю, что вам нужно создавать ссылку в RectWrapper, потому что onClick имеет один event параметр. И ссылку на элемент, по которому щелкнули, можно найти в случае:

onClick={(e) => {
    const thisRef = e.target;
    console.log(thisRef );
    ...

Вот рабочая версия без useRef: https://codesandbox.io/s/peaceful-brook-je8qo

...