React - 上下文问题 - raphael反应
我正在使用React和Raphael进行一个项目,而且我正面临一个我无法解决的上下文问题。React - 上下文问题 - raphael反应
代码的简化版本如下:
import React from 'react';
import {Raphael,Paper,Set,Circle,Ellipse,Image,Rect,Text,Path,Line} from 'react-raphael';
export default class PlanCdf extends React.Component {
\t onmouseover(){
\t \t console.log(this);
\t \t console.log(this.props.project);
\t }
\t drawTasks() {
\t \t return this.props.tasks.map((task) => {
\t \t \t return <Path mouseover={this.onmouseover} key={task._id} d={coords} attr={{"fill":"#444444", "stroke-width" : "2"}} />
\t \t })
\t }
\t render() {
\t \t return(
\t \t \t <Paper className={"paper"} width={this.state.paperWidth} height={this.state.paperHeight}>
\t \t \t \t <Set>
\t \t \t \t \t { this.drawTasks() }
\t \t \t \t </Set>
\t \t \t </Paper>
\t \t)
\t }
}
在我的onmouseover功能,我想访问两个方面:为了访问状态和道具的一般情况和Path上下文为了在onmouseover时改变路径的属性,但不知何故,我总是设法得到两个中的一个。
我从路径中获取这个上下文(如上例所示),但无法访问this.state。 或者如果我绑定我得到完整的,但不能访问我的路径了。 。
也许简单的绑定问题我不明白,但不能管理,以找到一个解决方案
---编辑---
这就是我目前的处境:
import React from 'react';
import {Raphael,Paper,Set,Circle,Ellipse,Image,Rect,Text,Path,Line} from 'react-raphael';
export default class PlanCdf extends React.Component {
constructor(props) {
super(props);
this.drawTasks = this.drawTasks.bind(this);
}
onmouseover(){
console.log(this.state);
}
drawTasks() {
return this.props.tasks.map((task) => {
return <PathWrapper mouseover={this.onmouseover} key={task._id} d={coords} attr={{"fill":"#444444", "stroke-width" : "3"}} />
})
}
render() {
return(
<Paper className={"paper"} width={this.state.paperWidth} height={this.state.paperHeight}>
<Set>
{ this.drawTasks() }
</Set>
</Paper>
)
}
}
export class PathWrapper extends React.Component {
constructor(props){
super(props);
}
onmouseover() {
console.log(this)
this.attr({'stroke-width':'5'})
this.props.mouseover()
}
render() {
return <Path mouseover={this.onmouseover} d={this.props.d} attr={this.props.attr} />
}
}
按照建议,我可以在新的PathWrapper组件中更改attr。但我仍然无法进入该州。我试图调用发送到道具的功能来访问父功能,但我不能,因为我需要在路径上下文来改变属性......我或多或少地将pb移动到子组件
好了,问题就解决了。包装是不是正确的解决方案,但在这里,你去为那些有兴趣:
import React from 'react';
import {Raphael,Paper,Set,Circle,Ellipse,Image,Rect,Text,Path,Line} from 'react-raphael';
export default class PlanCdf extends React.Component {
constructor(props) {
super(props);
this.drawTasks = this.drawTasks.bind(this);
}
onmouseover(raphael_context){
console.log(this.state);
raphael_context.attr({'stroke-width':'5'});
}
drawTasks() {
return this.props.tasks.map((task) => {
var self = this;
return <Path mouseover={function() { return self.onmouseover(this) }} key={task._id} d={coords} attr={{"fill":"#444444", "stroke-width" : "3"}} />
})
}
render() {
return(
<Paper className={"paper"} width={this.state.paperWidth} height={this.state.paperHeight}>
<Set>
{ this.drawTasks() }
</Set>
</Paper>
)
}
}
现在的onmouseover都在我访问路径拉斐尔对象和对父母的状态!
由于您正在使用React类,因此您需要在构造函数中绑定您的方法,或使用箭头函数绑定到反应上下文。
对于来自PlanCdf组件访问“ATTR”你不能这样做,从“PlanCdf”,因为它会在路径组成的props
(之子PlanCdf)可用。
我建议你换Path
的组件,然后使用该包装组件的this
背景下,从通过道具获得“attr
”,然后调用的onmouseover方法从包装成分,你可以在“ATTR”从访问this.props.attr
。
您可能还需要存储“attr
”在PathWrapper
本地状态,如果你想变异它(那么你的路径包装组件将不会被功能组件)
import React from 'react';
import {Raphael,Paper,Set,Circle,Ellipse,Image,Rect,Text,Path,Line} from 'react-raphael';
export default class PlanCdf extends React.Component {
constructor() {
super(props);
this.drawTasks = this.drawTasks.bind(this);
}
\t onmouseover(){
\t \t console.log(this);
\t \t console.log(this.props.attr);
// Here you can the attr to a different color
\t }
\t drawTasks() {
\t \t return this.props.tasks.map((task) => {
\t \t \t return <PathWrapper mouseover={this.onmouseover} key={task._id} d={coords} attr={{"fill":"#444444", "stroke-width" : "2"}} />
\t \t })
\t }
\t render() {
\t \t return(
\t \t \t <Paper className={"paper"} width={this.state.paperWidth} height={this.state.paperHeight}>
\t \t \t \t <Set>
\t \t \t \t \t { this.drawTasks() }
\t \t \t \t </Set>
\t \t \t </Paper>
\t \t)
\t }
}
const PathWrapper = ({mouseover, key, d, attr}) => {
return (<Path mouseover={onmouseover} key={key} d={d} attr={attr} />);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
编辑:请看下面的运行代码。为了简单起见,我已经删除了复数,但其他所有的东西都是一样的。
class PlanCdf extends React.Component {
constructor(props) {
super(props);
this.state = {
attr : {
"backgroundColor":"#444444",
"border" : "3px solid green"
},
oldattr : {
}
};
this.drawTasks = this.drawTasks.bind(this);
this.onmouseover = this.onmouseover.bind(this);
this.onmouseout = this.onmouseout.bind(this);
}
onmouseover(){
const newAttr = {
"backgroundColor":"#444444",
"border" : "1px solid green"
};
this.setState((prevState, props) => ({ attr : newAttr, oldattr : prevState.attr }));
}
onmouseout() {
this.setState((prevState, props) => ({attr : prevState.oldattr, oldattr : prevState.attr }));
}
drawTasks() {
return this.props.tasks.map((task) => {
return <PathWrapper mouseover={this.onmouseover} mouseout={this.onmouseout} key={task._id} attr={this.state.attr} />
})
}
render() {
return(
<div>
{ this.drawTasks() }
</div>
)
}
}
class PathWrapper extends React.Component {
constructor(props){
super(props);
}
render() {
return <div className="test" style={this.props.attr} onMouseOver={this.props.mouseover} onMouseOut={this.props.mouseout} > This is test </div>;
}
}
const tasks = [{_id:1},{_id:2}];
ReactDOM.render(
<PlanCdf tasks={tasks} />,
document.getElementById('root')
);
.test {
width: 100px;
height:150px;
border: 1px solid red;
margin : 5px;
padding : 5px;
color : white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
我觉得我们是在正确的方向,但它是sitll不工作。我正在编辑相应的问题 – Ivo