【发布时间】:2017-07-20 14:07:57
【问题描述】:
我有一个 React 组件,它的可见性和位置可以由用户更改。
通过添加和删除 CSS 类的可见性,通过函数的位置,将拖放后的新位置设置为顶部和左侧。
这可行,但我的问题是 React 不会更新样式(因此不会将位置重写为初始位置),当组件为可见性重新渲染时。
class MoveableCard extends React.Component {
...
render() {
...
return <div className={(this.props.isVisible ? '' : 'hide')}
draggable="true" onDragStart={dragStart}
style={{top:'initial', left:'initial'}}>
...
</div>
}
}
function dragStart(event) {
var style = window.getComputedStyle(event.target, null)
event.dataTransfer.setData("text/plain", JSON.stringify({
id:event.target.getAttribute('data-reactid'),
x:(parseInt(style.getPropertyValue("left"),10) - event.clientX),
y:(parseInt(style.getPropertyValue("top"),10) - event.clientY)
}))
}
function dragOver(event) {
event.preventDefault()
return false
}
function drop(event) {
let data = JSON.parse(event.dataTransfer.getData("text/plain"))
let el = document.querySelectorAll("[data-reactid='" + data.id + "']")[0]
el.style.left = (event.clientX + parseInt(data.x, 10)) + 'px'
el.style.top = (event.clientY + parseInt(data.y, 10)) + 'px'
event.preventDefault()
return false
}
document.body.addEventListener('dragover',dragOver,false)
document.body.addEventListener('drop',drop,false)
第一次渲染卡片时,样式类似于style="top: initial; left: initial;"。
当卡片被移动时,样式看起来像style="top: 162px; left: 320px;"。
当卡片关闭时,类hide被添加,但样式保持style="top: 162px; left: 320px;",不管我如何创建样式对象。
那么,我怎样才能强制 React 更新样式呢? 还是有其他方法可以做到这一点?
【问题讨论】:
-
我认为你错过了 React 的重点。您应该使用 React 的
state并调用this.setState而不是操纵 dom 元素的样式,这将自动为您调用renderfacebook.github.io/react/docs/state-and-lifecycle.html -
就像上面的评论一样,您应该使用 react API 库来控制您的元素/组件,以便它可以在 state/prop 更改时重新渲染。直接使用 DOM 与 react 在幕后所做的相反,因为 react 创建了一个虚拟 DOM,而您在常规 DOM 上添加了一个事件侦听器。注册到 DOM 元素的任何事件都有效,但不会被 react 重新渲染,因为 react 是在单独的 DOM(虚拟 DOM)上运行的
-
但是我怎样才能只通过 dom 元素访问我的 React 对象呢?包含我的位置的放置函数在我放置元素的元素上调用,而不是在移动的元素上调用。
-
你可以给它添加一个引用:facebook.github.io/react/docs/refs-and-the-dom.html 或者使用父组件作为属性传递一个回调。 medium.com/@ruthmpardee/…
标签: javascript css reactjs drag-and-drop