如何将 React.createclass 转换为 Class 组件?
How Can I convert React.createclass to Class Component?
我在react js中举了一个例子,拖动某些div从这里
http://jsfiddle.net/Af9Jt/2/
现在它在 createClass 中,我需要将其转换为 class Draggable extends React.Component
以便将其导出到另一个组件中。这是代码
APP.JS
import React from 'react';
import './App.css';
import Draggable from './Draggable.js';
function App() {
return (
<React.Fragment>
<Draggable />
</React.Fragment>
);
}
export default App;
Draggable.js
import React from 'react';
export class Draggable extends React.Component{
constructor(props) {
super(props);
this.state = {
pos: {x: 0, y: 0},
dragging: false,
rel: null
};
this.onMouseMove = this.onMouseMove.bind(this);
this.onMouseDown = this.onMouseDown.bind(this);
this.onMouseUp = this.onMouseUp.bind(this);
}
// 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(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(e) {
console.log("1")
console.log(this.state);
if (e.button !== 0) return
this.setState({
dragging: true,
rel: {
x: e.pageX - e.nativeEvent.offsetX,
y: e.pageY - e.nativeEvent.offsetY
}
})
e.stopPropagation()
e.preventDefault()
}
onMouseUp(e) {
this.setState({dragging: false})
e.stopPropagation()
e.preventDefault()
}
onMouseMove(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() {
return(
<div
style={{position: "absolute", left: "175px", top: "65px", border: "2px solid rgb(170, 170, 85)", padding: "10px"}}
className="my-draggable" data-reactid=".r[2zxee]" id="messi"
onMouseDown={this.onMouseDown}
onMouseUp={this.onMouseUp}
onMouseDown={this.onMouseDown}
initialPos = {{x:0,y:0}}
>
Drag Me! See how children are passed through to the div!
</div>
)
}
}
export default Draggable;
在此代码中一切运行良好,显示了框,但我无法拖动 div,我无法弄清楚这是什么问题。我该如何解决这个问题?
这是我在 jsfiddle 中的示例代码
将其转换为 React.Component:
时我注意到了一些事情
- 你在渲染时从未使用过
this.state.pos
,所以即使变量中的位置发生变化,它也不会移动div。 <div>
的 style
属性只是 hard-coded 和 { left: "175px", top: "65px" }
- 您在
this.onMouseDown
函数中没有正确获取鼠标的位置,这导致它强制每个移动都在角落。
- 您从未将
this.onMouseMove
绑定到任何东西。取消注释掉大量注释掉的代码可以解决这个问题。
- 您放置在
<div>
中的 initialPos
属性完全没有任何作用。我在构造函数中将其转换为道具。
这是更新后的 JSFiddle link:https://jsfiddle.net/ogy4xd1c/3/
我将把它嵌入 Whosebug 的一个片段中。
class Draggable extends React.Component {
constructor(props) {
super(props);
this.state = {
pos: props.initialPos || {
x: 0,
y: 0
},
dragging: false,
rel: null
}
this.onMouseMove = this.onMouseMove.bind(this);
this.onMouseDown = this.onMouseDown.bind(this);
this.onMouseUp = this.onMouseUp.bind(this);
}
// calculate relative position to the mouse and set dragging=true
onMouseDown(e) {
if (e.button !== 0) return
const de = document.documentElement;
const box = ReactDOM.findDOMNode(this).getBoundingClientRect();
const top = box.top + window.pageYOffset - de.clientTop;
const left = box.left + window.pageXOffset - de.clientLeft;
this.setState({
dragging: true,
rel: {
x: e.pageX - left,
y: e.pageY - top,
}
})
e.stopPropagation()
e.preventDefault()
}
onMouseUp(e) {
this.setState({
dragging: false
})
e.stopPropagation()
e.preventDefault()
}
onMouseMove(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()
}
componentDidUpdate(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)
}
}
render() {
return ( <div
style={{
position: "absolute",
left: this.state.pos.x,
top: this.state.pos.y,
border: "2px solid rgb(170, 170, 85)",
padding: "10px"
}}
className="my-draggable"
data-reactid=".r[2zxee]"
id="messi"
onMouseDown={this.onMouseDown}
className="my-draggable"
>
Drag Me! See how children are passed through to the div!
</div>
)
}
}
ReactDOM.render(<Draggable initialPos={{ x: 50, y: 20 }} />, document.querySelector("#root"));
.my-draggable {
cursor: pointer;
width: 200px;
height: 200px;
background-color: #cca;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
如果你想传入 children,你也可以使用这个修改后的版本:https://jsfiddle.net/hceLjz90/
class Draggable extends React.Component {
constructor(props) {
super(props);
this.state = {
pos: props.initialPos || {
x: 0,
y: 0
},
dragging: false,
rel: null
}
this.onMouseMove = this.onMouseMove.bind(this);
this.onMouseDown = this.onMouseDown.bind(this);
this.onMouseUp = this.onMouseUp.bind(this);
}
// calculate relative position to the mouse and set dragging=true
onMouseDown(e) {
if (e.button !== 0) return
const de = document.documentElement;
const box = ReactDOM.findDOMNode(this).getBoundingClientRect();
const top = box.top + window.pageYOffset - de.clientTop;
const left = box.left + window.pageXOffset - de.clientLeft;
this.setState({
dragging: true,
rel: {
x: e.pageX - left,
y: e.pageY - top,
}
})
e.stopPropagation()
e.preventDefault()
}
onMouseUp(e) {
this.setState({
dragging: false
})
e.stopPropagation()
e.preventDefault()
}
onMouseMove(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()
}
componentDidUpdate(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)
}
}
render() {
return ( <div
style={{
position: "absolute",
left: this.state.pos.x,
top: this.state.pos.y,
border: "2px solid rgb(170, 170, 85)",
padding: "10px"
}}
className="my-draggable"
data-reactid=".r[2zxee]"
id="messi"
onMouseDown={this.onMouseDown}
className="my-draggable"
>
{this.props.children}
</div>
)
}
}
ReactDOM.render(<Draggable initialPos={{ x: 50, y: 20 }}>
<h1>This is a child element</h1>
<p>This is also a child element</p>
</Draggable>, document.querySelector("#root"))
.my-draggable {
cursor: pointer;
width: 200px;
height: 200px;
background-color: #cca;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
我在react js中举了一个例子,拖动某些div从这里 http://jsfiddle.net/Af9Jt/2/
现在它在 createClass 中,我需要将其转换为 class Draggable extends React.Component
以便将其导出到另一个组件中。这是代码
APP.JS
import React from 'react';
import './App.css';
import Draggable from './Draggable.js';
function App() {
return (
<React.Fragment>
<Draggable />
</React.Fragment>
);
}
export default App;
Draggable.js
import React from 'react';
export class Draggable extends React.Component{
constructor(props) {
super(props);
this.state = {
pos: {x: 0, y: 0},
dragging: false,
rel: null
};
this.onMouseMove = this.onMouseMove.bind(this);
this.onMouseDown = this.onMouseDown.bind(this);
this.onMouseUp = this.onMouseUp.bind(this);
}
// 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(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(e) {
console.log("1")
console.log(this.state);
if (e.button !== 0) return
this.setState({
dragging: true,
rel: {
x: e.pageX - e.nativeEvent.offsetX,
y: e.pageY - e.nativeEvent.offsetY
}
})
e.stopPropagation()
e.preventDefault()
}
onMouseUp(e) {
this.setState({dragging: false})
e.stopPropagation()
e.preventDefault()
}
onMouseMove(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() {
return(
<div
style={{position: "absolute", left: "175px", top: "65px", border: "2px solid rgb(170, 170, 85)", padding: "10px"}}
className="my-draggable" data-reactid=".r[2zxee]" id="messi"
onMouseDown={this.onMouseDown}
onMouseUp={this.onMouseUp}
onMouseDown={this.onMouseDown}
initialPos = {{x:0,y:0}}
>
Drag Me! See how children are passed through to the div!
</div>
)
}
}
export default Draggable;
在此代码中一切运行良好,显示了框,但我无法拖动 div,我无法弄清楚这是什么问题。我该如何解决这个问题?
这是我在 jsfiddle 中的示例代码
将其转换为 React.Component:
时我注意到了一些事情- 你在渲染时从未使用过
this.state.pos
,所以即使变量中的位置发生变化,它也不会移动div。<div>
的style
属性只是 hard-coded 和{ left: "175px", top: "65px" }
- 您在
this.onMouseDown
函数中没有正确获取鼠标的位置,这导致它强制每个移动都在角落。 - 您从未将
this.onMouseMove
绑定到任何东西。取消注释掉大量注释掉的代码可以解决这个问题。 - 您放置在
<div>
中的initialPos
属性完全没有任何作用。我在构造函数中将其转换为道具。
这是更新后的 JSFiddle link:https://jsfiddle.net/ogy4xd1c/3/
我将把它嵌入 Whosebug 的一个片段中。
class Draggable extends React.Component {
constructor(props) {
super(props);
this.state = {
pos: props.initialPos || {
x: 0,
y: 0
},
dragging: false,
rel: null
}
this.onMouseMove = this.onMouseMove.bind(this);
this.onMouseDown = this.onMouseDown.bind(this);
this.onMouseUp = this.onMouseUp.bind(this);
}
// calculate relative position to the mouse and set dragging=true
onMouseDown(e) {
if (e.button !== 0) return
const de = document.documentElement;
const box = ReactDOM.findDOMNode(this).getBoundingClientRect();
const top = box.top + window.pageYOffset - de.clientTop;
const left = box.left + window.pageXOffset - de.clientLeft;
this.setState({
dragging: true,
rel: {
x: e.pageX - left,
y: e.pageY - top,
}
})
e.stopPropagation()
e.preventDefault()
}
onMouseUp(e) {
this.setState({
dragging: false
})
e.stopPropagation()
e.preventDefault()
}
onMouseMove(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()
}
componentDidUpdate(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)
}
}
render() {
return ( <div
style={{
position: "absolute",
left: this.state.pos.x,
top: this.state.pos.y,
border: "2px solid rgb(170, 170, 85)",
padding: "10px"
}}
className="my-draggable"
data-reactid=".r[2zxee]"
id="messi"
onMouseDown={this.onMouseDown}
className="my-draggable"
>
Drag Me! See how children are passed through to the div!
</div>
)
}
}
ReactDOM.render(<Draggable initialPos={{ x: 50, y: 20 }} />, document.querySelector("#root"));
.my-draggable {
cursor: pointer;
width: 200px;
height: 200px;
background-color: #cca;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
如果你想传入 children,你也可以使用这个修改后的版本:https://jsfiddle.net/hceLjz90/
class Draggable extends React.Component {
constructor(props) {
super(props);
this.state = {
pos: props.initialPos || {
x: 0,
y: 0
},
dragging: false,
rel: null
}
this.onMouseMove = this.onMouseMove.bind(this);
this.onMouseDown = this.onMouseDown.bind(this);
this.onMouseUp = this.onMouseUp.bind(this);
}
// calculate relative position to the mouse and set dragging=true
onMouseDown(e) {
if (e.button !== 0) return
const de = document.documentElement;
const box = ReactDOM.findDOMNode(this).getBoundingClientRect();
const top = box.top + window.pageYOffset - de.clientTop;
const left = box.left + window.pageXOffset - de.clientLeft;
this.setState({
dragging: true,
rel: {
x: e.pageX - left,
y: e.pageY - top,
}
})
e.stopPropagation()
e.preventDefault()
}
onMouseUp(e) {
this.setState({
dragging: false
})
e.stopPropagation()
e.preventDefault()
}
onMouseMove(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()
}
componentDidUpdate(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)
}
}
render() {
return ( <div
style={{
position: "absolute",
left: this.state.pos.x,
top: this.state.pos.y,
border: "2px solid rgb(170, 170, 85)",
padding: "10px"
}}
className="my-draggable"
data-reactid=".r[2zxee]"
id="messi"
onMouseDown={this.onMouseDown}
className="my-draggable"
>
{this.props.children}
</div>
)
}
}
ReactDOM.render(<Draggable initialPos={{ x: 50, y: 20 }}>
<h1>This is a child element</h1>
<p>This is also a child element</p>
</Draggable>, document.querySelector("#root"))
.my-draggable {
cursor: pointer;
width: 200px;
height: 200px;
background-color: #cca;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>