React-dnd: monitor.isDragging () às vezes retorna falso quando deveria retornar verdadeiro

Criado em 9 jul. 2015  ·  12Comentários  ·  Fonte: react-dnd/react-dnd

Ao usar duas ou mais listas classificáveis ​​interoperáveis, monitor.isDragging () retorna falso às vezes, quando deveria retornar verdadeiro ao arrastar um item de um contêiner para outro.

Configuração: começando com a demonstração simples classificável, adicione outro contêiner e conjunto de objetos classificáveis. Os cartões devem ser arrastados de um contêiner para outro, classificáveis ​​dentro de seu próprio contêiner e classificáveis ​​à medida que são arrastados de um contêiner para outro.

O problema ocorre ao mover um cartão de um contêiner para outro. O componente do cartão depende da propriedade isDragging (injetada pelo decorador DragSource) para determinar a opacidade, no entanto, quando o item é arrastado de um contêiner para outro, o monitor global altera o sourceId que não corresponde mais ao componente arrastado e acaba retornando false para chamadas para isDragging quando deveria retornar true.

Uma vez que o dragsource já requer uma chave globalmente exclusiva por objeto arrastável (outras coisas realmente se comportam mal se as chaves do seu componente arrastável mudarem a qualquer momento), o código pode usar essa chave ao designar o sourceId para que arrastar de um contêiner funcione corretamente?

Deixe-me saber se você precisa ver o código de exemplo. Meu código que demonstra esse problema é baseado em uma demonstração simples e classificável.

Comentários muito úteis

Para que isDragging trabalhe na árvore de componentes, implemente manualmente isDragging em sua fonte de arrastar.

const ingredientSource = {
    beginDrag(props) {
        return { ingredient: props.ingredient };
    },
    isDragging(props, monitor) {
        return props.ingredient === monitor.getItem().ingredient;
    }
};

Veja DragSource docs :

isDragging(props, monitor) : opcional. Por padrão, apenas a fonte de arrastar que iniciou a operação de arrastar é considerada como arrastando. Você pode substituir esse comportamento definindo um método isDragging . Ele pode retornar algo como props.id === monitor.getItem().id . Faça isso se o componente original puder ser desmontado durante o arrasto e posteriormente “ressuscitado” com um pai diferente. Por exemplo, ao mover um cartão pelas listas em um quadro Kanban, você deseja que ele retenha a aparência arrastada - embora, tecnicamente, o componente seja desmontado e um diferente seja montado toda vez que você o mover para outra lista. _Observação: Você não pode chamar monitor.isDragging() dentro deste método._

Isso ajuda?

Todos 12 comentários

@amoenk Sim, precisaremos de um código de exemplo para ajudá-lo.

Obrigado pela ajuda! Aqui está o exemplo de trabalho: http://notlouieagain.com/~amoenk/dnd/

E este link para navegar pelo código desagregado: http://notlouieagain.com/~amoenk/dnd/js/

Oh, eu incluí o código de demonstração simples e classificável original lá também enquanto estava depurando, mas os componentes importantes são Ingredient e IngredientGroup.

Dei uma olhada no seu código e não consigo encontrar o componente DnDStudy . Você pode me mostrar o seu código completo e somente o seu. Você pode remover o código de demonstração.

Código de demonstração removido, o componente DnDStudy é um componente da página aqui: http://notlouieagain.com/~amoenk/dnd/js/pages/DnDStudy.react.js

Ok, dei uma olhada e acredito que pode ser um problema devido às chaves de IngredientGroup dentro de DnDStudy . Em vez de confiar no índice do array, tente usar algum id único semelhante ao de Ingredient dentro de IngredientGroup .

Código atualizado, mas ainda com o mesmo problema.

OK. Eu estava errado então.

@gaearon você pode ajudar?

Para que isDragging trabalhe na árvore de componentes, implemente manualmente isDragging em sua fonte de arrastar.

const ingredientSource = {
    beginDrag(props) {
        return { ingredient: props.ingredient };
    },
    isDragging(props, monitor) {
        return props.ingredient === monitor.getItem().ingredient;
    }
};

Veja DragSource docs :

isDragging(props, monitor) : opcional. Por padrão, apenas a fonte de arrastar que iniciou a operação de arrastar é considerada como arrastando. Você pode substituir esse comportamento definindo um método isDragging . Ele pode retornar algo como props.id === monitor.getItem().id . Faça isso se o componente original puder ser desmontado durante o arrasto e posteriormente “ressuscitado” com um pai diferente. Por exemplo, ao mover um cartão pelas listas em um quadro Kanban, você deseja que ele retenha a aparência arrastada - embora, tecnicamente, o componente seja desmontado e um diferente seja montado toda vez que você o mover para outra lista. _Observação: Você não pode chamar monitor.isDragging() dentro deste método._

Isso ajuda?

Funciona perfeitamente! Deve ter esquecido isso nos documentos.

Obrigado por toda sua ajuda! Vou fechar o tíquete.

Sem problemas. Feliz por ajudar.

meh! Links para http://notlouieagain.com/ não estão respondendo ...

Eu encontrei a causa raiz do meu problema. Tive que parar de usar o DragDropContextProvider para envolver meus DropTargets e DragSources. Veja o exemplo abaixo.
http://react-dnd.github.io/react-dnd/docs-drag-drop-context-provider.html

export default class YourApp {
    render() {
        return (
            <DragDropContextProvider backend={HTML5Backend}>
                /* ... */
            </DragDropContextProvider>
        )
    }
}

Em vez disso, tive que usar o DragDropContext para embrulhar minha classe inteira como abaixo.
http://react-dnd.github.io/react-dnd/docs-drag-drop-context.html

class YourApp {
    /* ... */
}
export default DragDropContext(HTML5Backend)(YourApp)

Isso resolveu imediatamente o problema para mim.

Esta página foi útil?
0 / 5 - 0 avaliações