反应 - 上下文问题 - raphael-react

时间:2017-10-17 04:53:25

标签: javascript reactjs 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 {
	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;
&#13;
&#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>

2 个答案:

答案 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对象,也可以访问父级的状态!