React-dnd: ネストされたDragSourceによる警告

作成日 2016年04月06日  ·  27コメント  ·  ソース: react-dnd/react-dnd

DragSourceでもあるコンポーネント内にDragSourceがある場合(つまり、ドラッグ可能なもの内で何かをドラッグする)、親コンポーネントがドラッグされるたびに、次の警告が表示されます。

Warning: setState(...): Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.
warning @   modules.js?hash=107dc56…:19491
getInternalInstanceReadyForUpdate   @   modules.js?hash=107dc56…:5476
ReactUpdateQueue.enqueueSetState    @   modules.js?hash=107dc56…:5617
ReactComponent.setState @   modules.js?hash=107dc56…:15132
handleChange    @   modules.js?hash=107dc56…:20844
handleChange    @   modules.js?hash=107dc56…:22861
dispatch    @   modules.js?hash=107dc56…:23568
addSource   @   modules.js?hash=107dc56…:23124
registerSource  @   modules.js?hash=107dc56…:21172
receiveType @   modules.js?hash=107dc56…:21099
receiveProps    @   modules.js?hash=107dc56…:21089
DragSource(NestedComponent) @   modules.js?hash=107dc56…:21062
ReactCompositeComponentMixin.mountComponent @   modules.js?hash=107dc56…:6679
ReactCompositeComponent_mountComponent  @   modules.js?hash=107dc56…:896
ReactReconciler.mountComponent  @   modules.js?hash=107dc56…:5167
ReactMultiChild.Mixin.mountChildren @   modules.js?hash=107dc56…:13562
ReactDOMComponent.Mixin._createContentMarkup    @   modules.js?hash=107dc56…:10901
ReactDOMComponent.Mixin.mountComponent  @   modules.js?hash=107dc56…:10789
ReactReconciler.mountComponent  @   modules.js?hash=107dc56…:5167
ReactCompositeComponentMixin._updateRenderedComponent   @   modules.js?hash=107dc56…:7101
ReactCompositeComponentMixin._performComponentUpdate    @   modules.js?hash=107dc56…:7075
ReactCompositeComponentMixin.updateComponent    @   modules.js?hash=107dc56…:7004
ReactCompositeComponent_updateComponent @   modules.js?hash=107dc56…:896
ReactCompositeComponentMixin.receiveComponent   @   modules.js?hash=107dc56…:6936
ReactReconciler.receiveComponent    @   modules.js?hash=107dc56…:5217
ReactCompositeComponentMixin._updateRenderedComponent   @   modules.js?hash=107dc56…:7093
ReactCompositeComponentMixin._performComponentUpdate    @   modules.js?hash=107dc56…:7075
ReactCompositeComponentMixin.updateComponent    @   modules.js?hash=107dc56…:7004
ReactCompositeComponent_updateComponent @   modules.js?hash=107dc56…:896
ReactCompositeComponentMixin.receiveComponent   @   modules.js?hash=107dc56…:6936
ReactReconciler.receiveComponent    @   modules.js?hash=107dc56…:5217
ReactCompositeComponentMixin._updateRenderedComponent   @   modules.js?hash=107dc56…:7093
ReactCompositeComponentMixin._performComponentUpdate    @   modules.js?hash=107dc56…:7075
ReactCompositeComponentMixin.updateComponent    @   modules.js?hash=107dc56…:7004
ReactCompositeComponent_updateComponent @   modules.js?hash=107dc56…:896
ReactCompositeComponentMixin.performUpdateIfNecessary   @   modules.js?hash=107dc56…:6952
ReactReconciler.performUpdateIfNecessary    @   modules.js?hash=107dc56…:5232
runBatchedUpdates   @   modules.js?hash=107dc56…:5832
Mixin.perform   @   modules.js?hash=107dc56…:6304
Mixin.perform   @   modules.js?hash=107dc56…:6304
assign.perform  @   modules.js?hash=107dc56…:5789
flushBatchedUpdates @   modules.js?hash=107dc56…:5850
ReactUpdates_flushBatchedUpdates    @   modules.js?hash=107dc56…:896
Mixin.closeAll  @   modules.js?hash=107dc56…:6370
Mixin.perform   @   modules.js?hash=107dc56…:6317
ReactDefaultBatchingStrategy.batchedUpdates @   modules.js?hash=107dc56…:10295
enqueueUpdate   @   modules.js?hash=107dc56…:5879
enqueueUpdate   @   modules.js?hash=107dc56…:5460
ReactUpdateQueue.enqueueSetState    @   modules.js?hash=107dc56…:5626
ReactComponent.setState @   modules.js?hash=107dc56…:15132
handleChange    @   modules.js?hash=107dc56…:21121
handleChange    @   modules.js?hash=107dc56…:22861
dispatch    @   modules.js?hash=107dc56…:23568
(anonymous function)    @   modules.js?hash=107dc56…:22100
endDragIfSourceWasRemovedFromDOM    @   modules.js?hash=107dc56…:29563
handleTopDrop   @   modules.js?hash=107dc56…:29860

この例は次のとおりです。

class ParentDraggable extends React.Component {
    render() {
        return this.props.connectDragSource(
            <NestedDraggable/>
        );
    }
}

//... Skip the code for containers

class NestedDraggable extends React.Component {
    render() {
        return this.props.connectDragSource(
            <div></div>
        );
    }
}

この問題は、親コンポーネントを再レンダリングすると、子のDragSource呼び出しがreceiveProps関数呼び出し中にsetStateを呼び出すという事実に起因すると思いますか?

triage wontfix

最も参考になるコメント

誰かに役立つ場合に備えて:カスタムドラッグレイヤーでドラッグソースであるコンポーネントをレンダリングしているときに、便利だったのでこれに遭遇しました。 ドラッグソースコンポーネントを使用したのは、ドラッグしようとしたのと同じエンティティであったため、コード「DRY」を再利用して保持するのが理にかなっているからです。 すべてのdragSourceコードが含まれているという事実については考えていませんでした。振り返ってみると、カスタムドラッグレイヤーでレンダリングするものとしてドラッグソースを使用したくありません。

最終的に、コンポーネントを「ドラッグ可能な」バージョンに分割し、ベースコンポーネントをラップしてから、カスタムドラッグレイヤーでベースコンポーネントを使用しました。 これ以上の警告はありません、より良いコード! 👍

全てのコメント27件

:+1:

問題を再現したプロジェクトを提供していただけますか?

簡単な例を作成しようとしていますが、作業中のプライベートプロジェクト以外での複製に問題があります。 @nihtalak 、問題を

説明されている動作を示す小さなリポジトリは次のとおりです: https

不思議なことに、 Componentは、 monitor.getItem()リッスンしているときにのみこのエラーをスローします。 monitor.isDragging()リッスンしている場合は、次のブランチに示すように、正しく機能します: https

monitor.getItemType()リッスンするときにもエラーがスローされます: https

@ ebakan-興味深い。 isDraggingを使用するコードにこのバグが表示される原因は何でしょうか。 私はネストされたドラッグ可能なものでいくつかの奇妙なことをしているので、それはあなたが見ているのと同じバグの現れかもしれません。 再現にご協力いただきありがとうございます。

ドラッグ可能なものもネストしましたが、それが問題かどうかはわかりません。
新しいストアとリッスンしているコードを作成しているようです。 それが助けになるなら私はビデオを作りました:
http://screencast.com/t/qCrJRPAS2MYR

更新:問題が見つかりました。リスナーが残っていたので、私の場合はreact-dndが原因ではありませんでした。
Update2:話が早すぎた。 残ったリスナーを削除しても、警告が表示されます。

Dndを別のコンポーネントに追加したところ、ネストされたコンポーネントや複数のドラッグコンポーネントがなくても、この問題に気づきました。

少し掘り下げた後、問題はドラッグ中にコンポーネントをレンダリングするカスタムドラッグレイヤーに関連していることがわかりました。

ドラッグされているコンポーネントの代わりにテキストを配置すると、正常に機能します。 コンポーネント自体がドラッグソースです。

@jchristman @hakuninネストされたドラッグ可能isDragging基づいて条件付きでレンダリングされたドロップターゲットがあるときにCannot update during an existing state transitionに遭遇しました。 これはあなたの例のいずれかに当てはまりますか? このようなもの:

render() {
    var dropZone;
    if (this.props.isDragging) dropZone = <MyDropTarget />;
    return <div>
       <MyDragSource />
       {dropZone}
    </div>
}

ドラッグがアクティブなときにコンポーネントを追加および削除する代わりに、 display: none/blockを使用してターゲットを非表示にすることで、この問題を回避することになりました。

それ問題になると思います。 確認してお知らせします。 それは間違いなく私が今使っている構成です。

Naw-「ドロップ」が発生すると問題が発生します。 次に、コンポーネントの再レンダリングを試み、この警告をスローします。

ドラッグプレビューがDragSourceであるコンポーネントである場合に同じ警告が表示されました(これは行うべきではありません)。

@jchristmanこれに対する解決策を

ネストされたdragSourceを使用していて、ネストされたリソースを削除すると突然このエラーが発生し始めました。

例を挙げられますが、誰かが問題を解決したか、または適切な回避策があったかどうかを確認したいと思いました。

ドラッグプレビューがDragSourceであるコンポーネントである場合に同じ警告が表示されました(これは行うべきではありません)。

ありがとう@arjunu私の警告はこれによって引き起こされました!
私はまだ時々これらを持っているので、他の理由も修正される必要があると思います。 私の側にあるかもしれません:)

@ gharwood1 、私はそれが修正されるまで問題にただ

@gaearon誰かが引き下ろすことができるプロジェクトを作ったわけではありませんが、必要に応じてプロジェクトを作ることができると思います。

基本的に、私がここでやろうとしていることは有効です:

https://github.com/arackaf/booklist/blob/react-dnd-bug-freeze/react-redux/modules/subjects/components/subjectsList-es6.js

64行目の条件を無効にすると、すべて問題ありません

if (this.props.draggingSubject){
    effectiveChildren.push(this.props.draggingSubject);
}

しかし、ドラッグイベントの結果が小道具の変更とコンポーネントのレンダリングを開始するとすぐに、上記の警告が頻繁に吐き出され始めます。

私はこれをするべきではありませんか?

ユースケースは基本的に、ドロップターゲットで現在ドラッグされているアイテムを「プレビュー」することです。 上記は概念実証です。これが有効かどうかさえわからないため、まだReduxストアに接続されていません。


うーん、変更をSubjectDisplayContentにローカルに保持すれば問題ないように見えますが、変更がSubjectDisplay及ぶと、警告が発生し始めます。 したがって、基本的に、dropTargetが別のdropTargetを変更する小道具を送信する

私はまったく同じ問題を経験しています。 状況によっては、ネストされた各ドラッグ可能オブジェクトの周囲にDragDropContext作成できます。 ただし、カスタムDragLayerが必要になるとすぐには機能しません。

ネストされたdropTargetsを実行していることを除いて、同じエラーが発生しました。
ドキュメントを見て回った後、使ってみました

isOver(options):ドラッグ操作が進行中で、ポインターが現在所有者の上にある場合にtrueを返します。 オプションで、{shallow:true}を渡して、ネストされたターゲットではなく、所有者のみがホバーされているかどうかを厳密にチェックできます。

親dropTargetのcanDrop関数で(shallow is trueオプションを使用)、問題は解決しました。 同じことが他のいくつかのシナリオにも当てはまると思います。

@jchenjcこれを試しましたが、

FWIW:ネストされたドラッグソースとカスタムドラッグレイヤーの両方があります。 カスタムドラッグレイヤーを削除すると、メッセージが消えます。 スタックトレースを調べると、問題は次のようになります。

printWarning    @   warning.js?8a56:36
warning @   warning.js?8a56:60
getInternalInstanceReadyForUpdate   @   ReactUpdateQueue.js?6531:54
enqueueSetState @   ReactUpdateQueue.js?6531:200
ReactComponent.setState @   ReactComponent.js?702a:63
handleChange    @   DragLayer.js?1cbc:124 <--------------
handleChange    @   DragDropMonitor.js?0588:60

関連するコードはこちらです。 再レンダリングをトリガーするために、私の場合に状態が異なる可能性がある理由を調べます...

ドロップターゲット内にdragsource + droptargetがネストされていると、この問題が発生します。

これが発生した理由の一部は、gaearonが、ドラッグホバーの位置に基づいて何をするかを決定する単一のドロップターゲットにするのではなく、すべてのリストアイテムをドロップターゲットにすることによってリストのドラッグアンドドロップを行うことを想定していたためです。 後者の方法は、私が見た他のほとんどのDnDシステムがどのように動作するかです。

誰かに役立つ場合に備えて:カスタムドラッグレイヤーでドラッグソースであるコンポーネントをレンダリングしているときに、便利だったのでこれに遭遇しました。 ドラッグソースコンポーネントを使用したのは、ドラッグしようとしたのと同じエンティティであったため、コード「DRY」を再利用して保持するのが理にかなっているからです。 すべてのdragSourceコードが含まれているという事実については考えていませんでした。振り返ってみると、カスタムドラッグレイヤーでレンダリングするものとしてドラッグソースを使用したくありません。

最終的に、コンポーネントを「ドラッグ可能な」バージョンに分割し、ベースコンポーネントをラップしてから、カスタムドラッグレイヤーでベースコンポーネントを使用しました。 これ以上の警告はありません、より良いコード! 👍

@davidjoy woah、共有してくれてありがとう! 私は同じことをしています、それも試す必要があります!

@davidjoyちょうど私のものも修正しました。 あなたの提案は、カスタムレイヤーにDragSourceなどを使用しないことを示しています。 私がしたことは、カスタムドラッグレイヤーでDragSourceなしでネイキッドコンポーネントを使用することでしたが、それでうまくいきました。

この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。

このページは役に立ちましたか?
0 / 5 - 0 評価