React - 上下文问题 - raphael-react

React - Context issue - raphael-react

我正在制作一个同时使用 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>
  )
 }
}

在我的 onmouseover 函数中,我想访问两个上下文:一般上下文以访问状态和道具,以及路径上下文以在 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 组件中的属性。但我仍然无法访问该州。我试图调用发送到 props 中的函数来访问父函数,但我不能,因为我需要在路径上下文中更改属性...我或多或少地将 pb 移到了子组件

由于您使用的是 React class,您需要在构造函数中绑定您的方法或使用箭头函数绑定到 React 上下文。

要从 PlanCdf 组件访问 "attr" 你不能从 "PlanCdf" 因为它将在路径组件(PlanCdf 的子组件)的 props 中可用。

我建议你将 Path 包装在一个组件中,然后使用该 Wrapper 组件的 this 上下文从传递的道具中获取“attr”,然后调用 onmouseover 方法从包装器组件,您可以从 this.props.attr 访问 "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} />);
};
<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>

编辑:请查看下面的 运行 代码。为简单起见,我删除了 rapheal,但所有其他内容都相同。

 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>

好的,问题解决了。 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 对象,也可以访问父对象的状态!