在React中数组中的所有元素中更新相同的值

时间:2018-07-27 11:19:55

标签: javascript reactjs

我遇到了问题。我在单击和拖动时绘制矩形。我将这些矩形存储在数组中。每当我将新制作的Rectangle推入数组时,旧存储的矩形都会更新为最后推入的矩形。例如-假设我的数组(命名数据)包含的矩形为-[矩形1,矩形2]。现在,如果我添加第三个矩形,则更新后的数组就像-[矩形3,矩形3,矩形3]。 请告诉我我错了,并帮助我解决此问题。

//I am drawing rectangles in handleMouseMove function and updating the array in handleMouseUp. I am using var data = [] to store array

import React from 'react';

var rect = {};
var shape = {};
var data = [];

export default class MyCanvas extends React.Component {
    constructor(props) {
        super (props);

        this.state = {
            imageLink : 'some link',
            shapes : [],
            isDown : false,
        };

        this.handleClick = this.handleClick.bind (this);
        this.hanldeMouseMove = this.hanldeMouseMove.bind (this);        
        this.handleMouseDown = this.handleMouseDown.bind (this);        
        this.handleMouseUp = this.handleMouseUp.bind (this);        
    }

    componentDidMount() {
        const canvas = this.refs.canvas;
        const ctx = canvas.getContext ("2d");

        const img = this.refs.image;

        canvas.height = img.height;
        canvas.width = img.width;

        img.onload = () => {
            ctx.drawImage (img, 0, 0);
        }

        var rectX = canvas.offsetLeft;
        var rectY = canvas.offsetTop;

        canvas.addEventListener ('mousemove', (e) => {this.hanldeMouseMove (e, canvas, img)}, false);
        canvas.addEventListener ('mousedown', (e) => {this.handleMouseDown (e)}, false);
        canvas.addEventListener ('mouseup', () => {this.handleMouseUp(canvas)}, false);
    }

    hanldeMouseMove(e, canvas, img) {
        if (this.state.isDown) {
            rect.w = (e.pageX - canvas.offsetLeft) - rect.startX;
            rect.h = (e.pageY - canvas.offsetTop) - rect.startY ;

            const ctx = canvas.getContext ("2d");

            // Rectangles are drawn here
            ctx.clearRect(rect.startX, rect.startY, rect.w, rect.h);
            ctx.drawImage(img, 0, 0);
            ctx.strokeRect (rect.startX, rect.startY, rect.w, rect.h);

            shape = rect;
        }
    }

    handleMouseDown(e) {
        rect.startX = e.offsetX;
        rect.startY = e.offsetY;
        this.setState ({isDown : true});

    }

    // updating the array here
    handleMouseUp(canvas) {
        this.setState ({isDown : false});
        data.push(shape);
        console.log(data);
    }

    render() {
        return (
            <div className="container">
                <canvas ref = "canvas" />
                <img ref = "image" alt = "Link is Broken" src = {this.state.imageLink} className = "d-none" />
            </ div>
        );
    }
}

2 个答案:

答案 0 :(得分:1)

rect有一个引用,并且每次在数组中都会对其进行复制和更新。因此,数组中的所有元素都显示相同的元素。

代替

shape = rect;

喜欢这个,

shape = Object.assign({},rect);

答案 1 :(得分:0)

数据对象应该处于您的状态,并且必须记住React可以与不可变对象一起使用。

 handleMouseUp(canvas) {
    var newDataArray = this.state.data.slice();    
    newDataArray.push(shape);   
    this.setState({data:newDataArray})  
 }  

this.state.data.slice()创建数组的浅表副本,使其不可变

使用ES6,您还可以使用更好的方法,

handleMouseUp(canvas) {
    this.setState(previousState => ({
        data: [...previousState.data, shape]
    }));
}