accept и canDrop (свойства useDrop) не работают должным образом, чтобы предотвратить использование дублированных типов элементов - PullRequest
1 голос
/ 22 октября 2019

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

Сначала я попытался создать экземпляр массиваfreeCategories, который включает в себя все категории слов, затем перебирает переменную состояния currentPhrase (также массив) и удаляет каждую категорию, которая используется в настоящее время. реквизит, а затем использовать его в качестве значения для «принять» в useDrop. Это просто пропускало что-либо, независимо от того, что было в массиве freeCategories.

Мое второе решение состояло в том, чтобы выполнить эту логику над объектом перетаскивания. Если категория слова все еще доступна, она будет удалена из freeCategories, а ее тип будет «word-usable» или «word-block», если это не так. Если для параметра перенаправления цели назначения установлено значение «word-usable», оно все равно будет принимать что-либо, даже если его тип возвращался как «заблокированный словом».

Наконец, я попытался добавить свойство canDrop для useDrop. Это проверило массив freeCategories (переданный в реквизитах) по типу элемента (теперь возвращается к категории слова). Это привело к тому, что цель отбрасывания блокирует все, а canDrop возвращает false, даже если тип слова был в массиве свободных категорий. Когда я попытался переключить монитор с !! monitor.canDrop на! Monitor.canDrop, теперь он выглядит так, как будто он примет любое слово, но при отбрасывании он не запускает функцию сброса.

Функция, которая создаетjsx фразы:

function currentPhraseDisp() {
let freeCategories = ["Form", "Element", "Verb"];
        currentPhrase.forEach(word => freeCategories.splice(freeCategories.indexOf(word.category), 1));
        let startSpace = currentSpell.length < 3 ? <WordSpace start={true} accepts={freeCategories} addWordToCurrentPhrase={addWordToCurrentPhrase} /> : <></>;

return (
<>
            {startSpace}
            {currentPhrase.map((w, i) => {
                return (
                    <div key={i} className="current-phrase-word">
                        <div>{w['word']}</div>
                        <button>-</button>
                    </div>
                )
            })}
</>
)
}

Слова появляются как объекты в формате {слово: 'слово', категория: 'категория слова'}

Логика перетаскивания:

const [{ isDragging }, drag] = useDrag({
        /*Used in the second solution*/ item: { type: 'word-usable', id: props.word },
        item: { type: props.word.category, id: props.word},
        collect: monitor => ({
            isDragging: !!monitor.isDragging()
        })
    })

Логика удаления:

const [{ isOver, canDrop }, drop] = useDrop({
        accept: props.accepts,

/*Used in solution 3
        canDrop: (item) => {
            props.accepts.includes(item.type);
        },
*/
        drop: (item) => {
            props.addWordToCurrentPhrase(item.id, props.start);
        },
        collect: monitor => ({
            isOver: !!monitor.isOver(),
            canDrop: !!monitor.canDrop()
        })
    })

Мне бы хотелось, чтобы эти компоненты позволили пользователю перетаскивать только один из любого данного типа слова в currentPhrase. До сих пор мои результаты заключались в том, что цель отбрасывания принимает все слова или нет слов. Если кто-нибудь может помочь мне понять, что происходит с реакцией, я был бы признателен, потому что похоже, что он не позволит принимать какие-либо изменения или типы элементов при повторном отображении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...