Search code examples
reactjstypescriptwebpackmobxreact-beautiful-dnd

React App using react-beautiful-dnd ERROR "Unable to find any drag handles in the context '0' "


What is the promlem?

PlayerList.tsx

import React, { FC } from "react";
import players from "../../store/players";
import { observer } from "mobx-react-lite";
import { Draggable } from "react-beautiful-dnd";
import PlayerCard from "./../PlayerCard/PlayerCard";

const PlayerList: FC = observer(() => {
    return (
        <>
            {players.playerList.map((player, index) => (
                <Draggable
                    key={player.steamId}
                    draggableId={player.steamId}
                    index={index}
                >
                    {(provided) => (
                        <PlayerCard
                            playerinfo={player}
                            {...provided.draggableProps}
                            {...provided.dragHandleProps}
                            innerRef={provided.innerRef}
                        />
                    )}
                </Draggable>
            ))}
        </>
    );
});

export default PlayerList;

PlayerCard.tsx:

import React, { forwardRef } from "react";
import styles from "./PlayerCard.module.scss";
import { IPlayerInfo } from "./../../types/player";

interface PlayerCardProps {
    playerinfo: IPlayerInfo;
    innerRef: any;
}

function PlayerCard ({playerinfo, innerRef}:PlayerCardProps){
    const {fullName} = playerinfo;
    return (
        <div className={styles.card} ref={innerRef}>
            <div>
                <span>{fullName}</span>
            </div>
            <button> + </button>
        </div>
    );
};

export default PlayerCard;

The page I am only using react-beautiful-dnd in.

import React, { useEffect, useState } from "react";
import PlayerList from "../../components/PlayerList/PlayerList";
import players from "../../store/players";
import styles from "./RandomizerPage.module.scss";
import { useNavigate } from "react-router";
import axios from "../../axios";
import { DragDropContext, Droppable, DropResult } from "react-beautiful-dnd";

const RandomizerPage = () => {
    const [name, setName] = useState("");
    const [steamId, setURL] = useState("");
    const [mmr, setMMR] = useState("");

    const nav = useNavigate();
    const onDragEndHandle = (result: DropResult) => {
        console.log(result);

        // const from:IMove = {
        //     index: result
        // }
        // const to:IMove = {

        // }
        // players.move(from, to)
    };

    useEffect(() => {
        const user = JSON.parse(localStorage.getItem("user") || "null");
        if (user) {
            axios.defaults.headers["authorization"] = user.token;
            players.fetchPlayers();
        } else nav("/login");
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    return (
        <>
            <div>
                <input
                    type="text"
                    placeholder="Имя"
                    value={name}
                    onChange={(e) => {
                        setName(e.target.value);
                    }}
                />
                <input
                    type="text"
                    placeholder="steamId"
                    value={steamId}
                    onChange={(e) => {
                        setURL(e.target.value);
                    }}
                />
                <input
                    type="text"
                    value={mmr}
                    placeholder="mmr"
                    onChange={(e) => {
                        const text = e.target.value;
                        if (text.match(/^[0-9]*$/)) {
                            setMMR(text);
                        }
                    }}
                />
                <button
                    onClick={() => {
                        if (name && steamId && mmr) {
                            const newPlayer = {
                                fullName: name,
                                steamId: steamId,
                                mmr: parseInt(mmr),
                            };
                            axios
                                .post("players", newPlayer)
                                .then((res) => {
                                    if (res.status === 200) {
                                    }
                                })
                                .catch((err) => {
                                    console.log(err);
                                });

                            // if(res.status === 200) players.addPlayer(newPlayer)
                        }
                    }}
                >
                    Create
                </button>
            </div>
            <DragDropContext onDragEnd={onDragEndHandle}>
                <div className={styles.wrapper}>
                    <Droppable droppableId="randomPlayers">
                        {(provided) => (
                            <div
                                className={styles.column}
                                {...provided.droppableProps}
                                ref={provided.innerRef}
                            >
                                <h4>Переместите сюда игроков.</h4>
                                {provided.placeholder}
                            </div>
                        )}
                    </Droppable>
                    <Droppable droppableId="players">
                        {(provided) => (
                            <div
                                className={styles.column}
                                {...provided.droppableProps}
                                ref={provided.innerRef}
                            >
                                <h4>Игроки</h4>
                                <PlayerList />
                                {provided.placeholder}
                            </div>
                        )}
                    </Droppable>
                </div>
            </DragDropContext>
        </>
    );
};

export default RandomizerPage;

Any details you need? I will update the post.

SORRY! SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS SOMEMOREDETAILS


Solution

  • So I found a sollution for me.

    import React from "react";
    import styles from "./PlayerCard.module.scss";
    import { IPlayerInfo } from "./../../types/player";
    
    interface PlayerCardProps {
        playerinfo: IPlayerInfo;
        innerRef: any;
        rest?: any[];
    }
    
    function PlayerCard ({playerinfo, innerRef, ...rest}:PlayerCardProps){
        const {fullName} = playerinfo;
        return (
            <div className={styles.card} ref={innerRef} {...rest}>
                <div>
                    <span>{fullName}</span>
                </div>
                <button> + </button>
            </div>
        );
    };
    
    export default PlayerCard;