Состояние не обновляется в компоненте Drag and Drop Formik - PullRequest
0 голосов
/ 30 марта 2020

Я работаю над семейным деревом, где детей можно перевести к другим родителям. Проблема возникает, когда я переупорядочиваю семью с помощью перетаскивания (DnD), она не обновляется в объекте значений formik. Также, когда я удаляю дочерний элемент на DnD, он не обновляет объекты DnD, а обновляет объекты значений formik.

Ссылка Codesandbox: https://codesandbox.io/s/kind-hermann-lqve6 Ниже приведен код:

import React, { useState } from "react";
import ReactDOM from "react-dom";
import { Formik, FieldArray } from "formik";
import { Button, Form } from "antd";
import { DndProvider } from "react-dnd";
import HTML5Backend from "react-dnd-html5-backend";
import Sortly, { ContextProvider, useDrag, useDrop } from "react-sortly";

const FormItem = Form.Item;

const ItemRenderer = props => {
  const {
    index,
    data: { text, kids }
  } = props;
  const [, drag] = useDrag();
  const [, drop] = useDrop();

  return (
    <FieldArray
      name="family.parents"
      render={arrayHelpers => (
        <div ref={drop} style={{ width: "40vw" }} key={index}>
          <div
            ref={drag}
            style={{
              padding: "0.5rem 1rem",
              marginBottom: ".5rem",
              backgroundColor: "green",
              cursor: "move",
              color: "white",
              width: "320px"
            }}
          >
            {`${text}`}
            <FormItem style={{ display: "inline-block" }}>
              <span className="parent-utility">
                <Button
                  className="ant-btn"
                  shape="circle"
                  size="small"
                  style={{ color: "#ffa500" }}
                  onClick={() => arrayHelpers.remove(index)}
                >
                  Delete
                </Button>
              </span>
            </FormItem>
          </div>
          <KSortableTree kidsTree={kids} position={index} />
        </div>
      )}
    />
  );
};

const ItemRendererA = props => {
  const {
    index,
    position,
    data: { text }
  } = props;
  const [, drag] = useDrag();
  const [, drop] = useDrop();

  return (
    <FieldArray
      name={`family.parents[${position}].kids`}
      render={arrayHelpers => (
        <>
          <div ref={drop} style={{ width: "40vw" }}>
            <div
              ref={drag}
              style={{
                border: "1px dashed #70B5DC",
                padding: "0.5rem 1rem",
                marginBottom: ".5rem",
                marginLeft: "3rem",
                backgroundColor: "white",
                cursor: "move",
                color: "#70B5DC",
                width: "17rem"
              }}
            >
              {`${text}`}
              <FormItem style={{ display: "inline-block" }}>
                <span className="answer-utility">
                  <Button
                    className="ant-btn"
                    shape="circle"
                    size="small"
                    style={{ color: "#ffa500" }}
                    onClick={() => {
                      arrayHelpers.remove(index);
                    }}
                  >
                    Delete
                  </Button>
                </span>
              </FormItem>
            </div>
          </div>
        </>
      )}
    />
  );
};

const PSortableTree = parentTree => {
  const [items, setItems] = useState(parentTree.parentTree);
  const handleChange = newItems => {
    setItems(newItems);
  };

  return (
    <Sortly items={items} onChange={handleChange}>
      {props => <ItemRenderer {...props} />}
    </Sortly>
  );
};

const KSortableTree = kidsTree => {
  const [itemsA, setItemsA] = useState(kidsTree.kidsTree);
  const [positionA] = useState(kidsTree.position);
  const handleChangeA = newItemsA => {
    setItemsA(newItemsA);
  };

  return (
    <Sortly items={itemsA} onChange={handleChangeA}>
      {props => <ItemRendererA {...props} position={positionA} />}
    </Sortly>
  );
};

function FormDetail({ values, handleSubmit }) {
  return (
    <form onSubmit={handleSubmit}>
      <h3>Family Tree</h3>

      <DndProvider backend={HTML5Backend}>
        <ContextProvider>
          <PSortableTree parentTree={values.family.parents} />
        </ContextProvider>
      </DndProvider>

      <div
        style={{
          padding: 16,
          backgroundColor: "lightgrey",
          borderRadius: "8px",
          marginTop: "20px",
          maxWidth: "100vw"
        }}
      >
        {JSON.stringify(values)}
      </div>
    </form>
  );
}

function App() {
  return (
    <Formik
      enableReinitialize
      initialValues={{
        family: {
          id: "2da80396",
          parents: [
            {
              depth: 0,
              id: "01a3b77c",
              kids: [
                {
                  depth: "1",
                  id: "01a3b77d",
                  text: "A",
                  correct: true
                },
                {
                  depth: "1",
                  id: "02fd6f62",
                  text: "C",
                  correct: false
                }
              ],

              text: "Parent 1"
            },
            {
              depth: 0,
              id: "773a4170",
              kids: [
                {
                  depth: "1",
                  id: "773a4171",
                  text: "A",
                  correct: false
                },
                {
                  depth: "1",
                  id: "773a4172",
                  text: "B",
                  correct: true
                },
                {
                  depth: "1",
                  id: "773a4173",
                  text: "C",
                  correct: false
                }
              ],
              text: "Parent 2"
            },
            {
              depth: 0,
              id: "a3652131",
              kids: [
                {
                  depth: "1",
                  id: "1c081c33",
                  text: "G",
                  correct: false
                },
                {
                  depth: "1",
                  id: "a3654842",
                  text: "A",
                  correct: true
                },
                {
                  depth: "1",
                  id: "a3654843",
                  text: "B",
                  correct: false
                }
              ],
              text: "Parent 3"
            },
            {
              depth: 0,
              id: "a3654845",
              kids: [
                {
                  depth: "1",
                  id: "a3654846",
                  text: "A",
                  correct: true
                },
                {
                  depth: "1",
                  id: "a3654847",
                  text: "B",
                  correct: false
                }
              ],
              text: "Parent 4"
            },
            {
              depth: 0,
              id: "eb3dc4d9",
              kids: [
                {
                  depth: "1",
                  id: "2103b3bc",
                  text: "D",
                  correct: true
                },
                {
                  depth: "1",
                  id: "28650f35",
                  text: "A",
                  correct: false
                },
                {
                  depth: "1",
                  id: "699584c2",
                  text: "B",
                  correct: false
                },
                {
                  depth: "1",
                  id: "a9edd5c4",
                  text: "C",
                  correct: false
                }
              ],
              text: "Parent 5"
            }
          ],
          text: "Heading"
        }
      }}
      onSubmit={values => alert(JSON.stringify(values))}
      component={FormDetail}
    />
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...