[解決済み] Reactのコンポーネント/divをドラッグ可能にするおすすめの方法
質問
私はドラッグ可能な(つまり、マウスで再配置可能な)Reactコンポーネントを作りたいと思っていますが、それは必然的にグローバルな状態と散在するイベントハンドラを含むように思われます。私は、私のJSファイルのグローバル変数で、汚い方法でそれを行うことができ、おそらく素敵なクロージャーインターフェイスでそれを包むことさえできましたが、私はReactとよりよくかみ合う方法があるかどうかを知りたいのです。
また、私は生のJavaScriptでこれをやったことがないので、特にReactに関連して、私がすべてのコーナーケースを処理したことを確認するために、専門家がそれをどのように行うかを見たいと思います。
ありがとうございます。
どのように解決するのですか?
これはブログの記事にすべきかもしれませんが、かなりしっかりした例があります。
コメントでうまく説明できるはずですが、質問があれば教えてください。
そして、これが遊ぶためのバイオリンです。 http://jsfiddle.net/Af9Jt/2/
var Draggable = React.createClass({
getDefaultProps: function () {
return {
// allow the initial position to be passed in as a prop
initialPos: {x: 0, y: 0}
}
},
getInitialState: function () {
return {
pos: this.props.initialPos,
dragging: false,
rel: null // position relative to the cursor
}
},
// we could get away with not having this (and just having the listeners on
// our div), but then the experience would be possibly be janky. If there's
// anything w/ a higher z-index that gets in the way, then you're toast,
// etc.
componentDidUpdate: function (props, state) {
if (this.state.dragging && !state.dragging) {
document.addEventListener('mousemove', this.onMouseMove)
document.addEventListener('mouseup', this.onMouseUp)
} else if (!this.state.dragging && state.dragging) {
document.removeEventListener('mousemove', this.onMouseMove)
document.removeEventListener('mouseup', this.onMouseUp)
}
},
// calculate relative position to the mouse and set dragging=true
onMouseDown: function (e) {
// only left mouse button
if (e.button !== 0) return
var pos = $(this.getDOMNode()).offset()
this.setState({
dragging: true,
rel: {
x: e.pageX - pos.left,
y: e.pageY - pos.top
}
})
e.stopPropagation()
e.preventDefault()
},
onMouseUp: function (e) {
this.setState({dragging: false})
e.stopPropagation()
e.preventDefault()
},
onMouseMove: function (e) {
if (!this.state.dragging) return
this.setState({
pos: {
x: e.pageX - this.state.rel.x,
y: e.pageY - this.state.rel.y
}
})
e.stopPropagation()
e.preventDefault()
},
render: function () {
// transferPropsTo will merge style & other props passed into our
// component to also be on the child DIV.
return this.transferPropsTo(React.DOM.div({
onMouseDown: this.onMouseDown,
style: {
left: this.state.pos.x + 'px',
top: this.state.pos.y + 'px'
}
}, this.props.children))
}
})
国有化への思いなど
誰がどの状態を所有するかは、最初から答えるべき重要な質問です。ドラッグ可能なコンポーネントの場合、私はいくつかの異なるシナリオを見ることができました。
シナリオ 1
親がドラッガブルの現在の位置を所有している場合。この場合、ドラッガブルはまだ "ドラッグ中" の状態を所有していますが、この状態に対して
this.props.onChange(x, y)
を呼び出します。
シナリオ2
親は移動しない位置だけを所有すればよいので、ドラッガブルはドラッグする位置だけを所有しますが、マウスアップ時に
this.props.onChange(x, y)
を呼び出し、最終的な決定を親に委ねます。親がドラッガブルの最終位置を気に入らない場合、状態を更新せず、ドラッガブルはドラッグする前の初期位置に戻るようになります。
ミキシンまたはコンポーネント?
ssorallen 氏は、"dragable" はそれ自体よりも属性であるため、mixin としてよりよく機能するかもしれないと指摘しました。私のミキシンの経験は限られているので、ミキシンがどのように役立つのか、あるいは複雑な状況で邪魔になるのかを見たことがありません。これは最良の選択かもしれません。
関連
-
nullのプロパティinnerHTMLを読み取れません エラーメッセージ
-
[解決済み] setStateを呼び出さずにReactコンポーネントを強制的に再レンダリングすることは可能ですか?
-
[解決済み] Reactコンポーネント外でのクリックを検出する
-
[解決済み] React Nativeの<Text>コンポーネントに改行を挿入するにはどうすればよいですか?
-
[解決済み] react-router - ハンドラコンポーネントにpropsを渡す
-
[解決済み】Reactコンポーネントが再レンダリングされる原因を追跡する
-
[解決済み】あるリアクトコンポーネントを別のリアクトコンポーネントに渡して、最初のコンポーネントの内容をトランスクルードする方法は?
-
[解決済み】Reactコンポーネントはpropsから状態を初期化する
-
[解決済み】React / JSXの動的なコンポーネントの名前
-
[解決済み】マウントされていないコンポーネントに対してReactの状態更新を行うことができない
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Vueの要素ツリーコントロールに破線を追加する説明
-
Vueにシンプルなメモ帳機能を実装
-
Vueの一般的な組み込みディレクティブの説明
-
[解決済み】最大呼び出しスタックサイズ超過エラー
-
[解決済み】SyntaxError: JSONの位置1に予期しないトークンoがある。
-
[解決済み】リソースの読み込みに失敗した:Bind関数でサーバーが500(Internal Server Error)のステータスで応答した【非公開
-
[解決済み】Node.js Error: Cannot find module express
-
[解決済み】TypeErrorの解決方法。未定義またはヌルをオブジェクトに変換できない
-
[解決済み】JavaScriptでインラインIF文の書き方は?
-
[解決済み】リクエストに失敗していないのに、「TypeError: failed to fetch」が表示される。