2017-10-17 137 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