0
votes

enter image description here

Can I solve this problem with hooks?

And why it is not working right?

I start to use REACT DND and after I try to use drag and drop on the project everything went wrong.

I use as dependencies:

  • "@testing-library/jest-dom": "^4.2.4",

  • "@testing-library/react": "^9.5.0",

  • "@testing-library/user-event": "^7.2.1",
  • "node-sass": "^4.14.1",
  • "prop-types": "^15.7.2",
  • "react": "^16.13.1",
  • "react-dnd": "^11.1.3",
  • "react-dnd-html5-backend": "^11.1.3",
  • "react-dom": "^16.13.1",
  • "react-redux": "^7.2.0",
  • "react-scripts": "3.4.1",
  • "redux": "^4.0.5"

Deployed project - hungry-tree.surge.sh



src/components/todos/createTodo.js

import React, { useRef } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { useDrag, useDrop } from "react-dnd";
import actions from "../../actions";

const ItemTypes = {
  CARD: "todo",
};

function createTodo(props) {
  const currTodos = props.todos();
  return currTodos.map((elem, index) => {
    const ref = useRef(null);

    const [{ isDragging }, drag] = useDrag({
      item: { type: ItemTypes.CARD, index },
      collect: (monitor) => ({
        isDragging: monitor.isDragging(),
      }),
    });

    const [, drop] = useDrop({
      accept: ItemTypes.CARD,
      hover(item, monitor) {
        if (!ref.current) {
          return;
        }
        const dragIndex = item.index;
        const hoverIndex = index;
        // Don't replace items with themselves
        if (dragIndex === hoverIndex) {
          return;
        }
        const dragTodo = props.thirdData[dragIndex];
        const todoStart = props.thirdData.slice(0, hoverIndex - 1);
        const todoEnd = props.thirdData.slice(hoverIndex);
        todoStart.splice(todoStart.indexOf(dragTodo), 1);
        todoEnd.splice(todoStart.indexOf(dragTodo), 1);

        const withoutTodos = [...todoStart, dragTodo, ...todoEnd];
        props.setThirdData(withoutTodos);

        item.index = hoverIndex;
      },
    });
    drag(drop(ref));
    return (
      <li key={index} ref={drag} style={{ opacity: isDragging ? 0.5 : 1 }}>
        <span
          className={`todos_block-text ${
            elem.isComplete ? "todos_block-text_done" : ""
          }`}
          onClick={() => props.onDoneTodo(elem.label)}
        >
          {elem.label}
        </span>
        <button
          className="todos_block-trash"
          onClick={() => props.onDeleteTodo(elem.label)}
        >
          x
        </button>
      </li>
    );
  });
}

createTodo.propTypes = {
  thirdData: PropTypes.array,
  setThirdData: PropTypes.func,
};

const mapStateToProps = (store) => {
  return {
    thirdData: store.thirdData.data,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    setThirdData: (data) => dispatch(actions.setThirdData(data)),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(createTodo);
1
You're using hooks within a loop. If the loop size changes the hooks will be messed up. This is a bad practice, hooks should not be used conditionally.Brian Thompson

1 Answers

0
votes

this error appears because you are using hook inside a loop. Hooks implementation forbid this, you can find more here:

enter link description here

So probably you need to separate your todo items in separate component to use hook in the top of your component.