2017-10-17 84 views
2

我正在使用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移动到子组件

回答

0

好了,问题就解决了。包装是不是正确的解决方案,但在这里,你去为那些有兴趣:

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都在我访问路径拉斐尔对象和对父母的状态!

0

由于您正在使用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>

+0

我觉得我们是在正确的方向,但它是sitll不工作。我正在编辑相应的问题 – Ivo