在React.js中为组件添加多个形状?

时间:2016-06-17 05:08:32

标签: javascript reactjs components shapes

我目前正在尝试做两件事: 1.将多个形状添加到React类 2.有一个“选定”的形状,在选择时会改变颜色。

我认为我不会以正确的方式解决这个问题。首先,我正在使用对fillRect的一系列调用将所有形状添加到画布中,但这似乎不适合一般的React流程。此外,现在我只是试图将状态硬编码为等于一个矩形,然后将该形状渲染为不同的颜色,但它目前甚至没有出现在屏幕上(参见屏幕截图)。

我很感激有关这两个问题的任何建议!

相关代码:

class Shapes extends React.Component {

getInitialState() {
    var highlightedShape = {x:200, y:200, width:60, height:40};
    highlightedShape.width = 70;
}

componentDidMount() {
    this.updateCanvas();
}

updateCanvas() {
    const ctx = this.refs.canvas.getContext('2d');
    ctx.fillRect(0,0, 100, 100);
    ctx.fillRect(70,70,90,90);
    //my attempt at 'highlighting' the state's selected shape:
    ctx.fillStyle="red";
    ctx.fillRect(this.state.highlightedShape.x, this.state.highlightedShape.y, this.state.highlightedShape.width, this.state.highlightedShape.height);

}
render() {
    return (
        <canvas ref="canvas" width={300} height={300}/>
    );
  }
}

module.exports = Shapes

当前输出(甚至不显示所选形状):

3 个答案:

答案 0 :(得分:0)

您需要返回初始状态。现在,您的getInitialState调用返回undefined,因为您没有return语句。这意味着在updateCanvas()调用中,this.state.highlightedShape将被取消定义(您 也应该在控制台中出现错误)。

这样的事情:

getInitialState() {
    var highlightedShape = {x:200, y:200, width:60, height:40};
    highlightedShape.width = 70;
    return { highlightedShape: highlightedShape };
}

答案 1 :(得分:0)

您是否已开始使用画布?另一种方法是使用更适合React的svg,因为它是DOM..y。

https://jsfiddle.net/508n6skz/

var Shapes = React.createClass({
  render: function() {
    return (
    <svg width="500" height="500">
        <Rectangle x="10" y="10" width="100" height="200"></Rectangle>              
      <Rectangle x="20" y="30" width="50" height="100" selected="true"></Rectangle>
    </svg>);
  }
});

var Rectangle = React.createClass({
    _getColor: function(){
    return this.props.selected? 'red': 'blue';
  },
    render: function(){
    return (
    <rect fill={this._getColor()} x={this.props.x} y={this.props.y}
    width={this.props.width} height={this.props.height}></rect>
    );
  }
})

ReactDOM.render(
  <Shapes />,
  document.getElementById('container')
);

答案 2 :(得分:0)

通过在react中使用canvas,很简单的情况是不使用渲染函数的正常更新流,因为阴影dom diffing不支持画布内容。要解决这个问题,您需要告诉我们如何使用componentDidUpdate进行组件更新:

class Shapes extends React.Component {

getInitialState() {

    var highlightedShape = {x:200, y:200, width:60, height:40};
    // Remember to return the state object
    return {highlightedShape: highlightedShape} 
}

componentDidMount() {
    this.updateCanvas();
}

componentDidUpdate() {
    this.updateCanvas();
}

updateCanvas() {
    const ctx = this.refs.canvas.getContext('2d');
    ctx.fillRect(0,0, 100, 100);
    ctx.fillRect(70,70,90,90);
    //my attempt at 'highlighting' the state's selected shape:
    ctx.fillStyle="red";
    ctx.fillRect(this.state.highlightedShape.x, this.state.highlightedShape.y, this.state.highlightedShape.width, this.state.highlightedShape.height);

}
render() {
    return (
        <canvas ref="canvas" width={300} height={300}/>
    );
  }
}

module.exports = Shapes

要更新内容,您可以依赖于以下属性:

class Shapes extends React.Component {

getInitialState() {
    var highlightedShape = {x:200, y:200, width: this.props.shapeWidth, height:40};
}

componentWillReceiveProps() {
    // it's important to create a new object on state properties, because the state diffing is done by reference.
    this.setState(Object.assign({}, this.state.highligtedShape, {this.props.shapeWidth}))
}

// ...

}

您还可以看一下像react-canvas这样的可插拔画布解决方案,但是它们会让您远离铁,而不会帮助您了解正在发生的事情。