我正在使用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 {
onmouseover(){
console.log(this);
console.log(this.props.project);
}
drawTasks() {
return this.props.tasks.map((task) => {
return <Path mouseover={this.onmouseover} key={task._id} d={coords} attr={{"fill":"#444444", "stroke-width" : "2"}} />
})
}
render() {
return(
<Paper className={"paper"} width={this.state.paperWidth} height={this.state.paperHeight}>
<Set>
{ this.drawTasks() }
</Set>
</Paper>
)
}
}
&#13;
在我的onmouseover函数中,我想访问两个上下文:一般上下文,以便访问状态和道具以及Path上下文,以便在onmouseover时更改路径的attr,但不知怎的,我总是设法得到只有两个中的一个。
我从路径获取此上下文(如上例所示),但无法访问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。但我仍然无处可访问该州。我试图调用发送到props的函数来访问父函数,但我不能因为我需要在Path上下文中更改属性...我或多或少地将pb移动到子组件< / p>
答案 0 :(得分:0)
由于您使用的是React类,因此需要在构造函数中绑定方法或使用箭头函数绑定到响应上下文。
要从 PlanCdf 组件访问“attr”,您无法通过“PlanCdf”执行此操作,因为它将在{{1>中提供路径组件( PlanCdf 的子项)。
我建议你将props
包装在一个组件中,然后使用该Wrapper组件的Path
上下文从传递的props获取“this
”,然后从包装器调用onmouseover方法组件,您可以从attr
访问“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);
}
onmouseover(){
console.log(this);
console.log(this.props.attr);
// Here you can the attr to a different color
}
drawTasks() {
return this.props.tasks.map((task) => {
return <PathWrapper mouseover={this.onmouseover} key={task._id} d={coords} attr={{"fill":"#444444", "stroke-width" : "2"}} />
})
}
render() {
return(
<Paper className={"paper"} width={this.state.paperWidth} height={this.state.paperHeight}>
<Set>
{ this.drawTasks() }
</Set>
</Paper>
)
}
}
const PathWrapper = ({mouseover, key, d, attr}) => {
return (<Path mouseover={onmouseover} key={key} d={d} attr={attr} />);
};
编辑:请看下面的运行代码。我已经删除了rapheal以简化,但所有其他事情都是一样的。
<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;
}
答案 1 :(得分:0)
好的,问题解决了。 Wrapper不是正确的解决方案,但在这里你会选择那些感兴趣的人:
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中,我既可以访问Path Raphael对象,也可以访问父级的状态!