在更新一个状态时,多个集合会更新

时间:2018-03-19 16:23:31

标签: javascript html arrays reactjs

我是新手,我正在玩反应状态和组件。我制作了这个小应用程序,它从用户那里获取数组元素并随机改变其元素的位置。但是当我改变一个州时,另一个州也有机会。我有一个名为element array的状态,包含数字数组和另一个名为draw的数组,它将包含元素数组中随机移位元素位置的元素.problem是draw []的变化,element []也会改变。 我不希望元素[]改变。我只希望draw []包含element []数组中的元素,并在数组中包含新位置。

当我单击绘制按钮时,它会生成具有随机定位元素的数组,但它也会更改元素数组中包含元素原始位置的元素的位置。当我更新绘图数组

时,我不知道元素数组是如何变化的



const dom=document.getElementById("fn")
class Final extends React.Component{
    constructor(props)
    {
        super(props)
        this.state={
            element:[],
            draw: []
           
        }
        this.addElement=this.addElement.bind(this)
        this.drawer = this.drawer.bind(this)
    }
    drawer() {

        // shifting logic Fisher–Yates_shuffle
        var n = this.state.element.length
        var t=this.state.element
        var temp;
        while (n !== 0) {
            var rand = Math.floor(Math.random() * Math.floor(n))
            n--;
            temp = t[n]
            t[n] = t[rand]
            t[rand] = temp
        }
       this.setState( (prev)=> {
          
                return {draw:t} //update one state
         
       })
        
    }
    addElement(element)
    {
       if(!element)
       {
            return "ADD SOMETHING!"
       }
       else if(this.state.element.indexOf(element)>-1)
       {
        return "value Already Exists!"
       }
        this.setState((prev)=>{
            element=prev.element.concat(element) 
            return {element}
        })
    }
    render()
    {
        return(
            <div>
       
           < AddElement element = {
               this.state.element
           }
           addElement = {
               this.addElement
           }
           drawer = {
               this.drawer
           }
           />
           < Drawer draw={
               this.state.draw
            }
            />
           </div>
        )
    }
}

class AddElement extends React.Component{
    constructor(props)
    {
        super(props);
        this.add=this.add.bind(this)
        this.drawIt = this.drawIt.bind(this)
        this.state={
            error:undefined
        }
    }
    add(e)
    {
        e.preventDefault();
        const element=e.target.elements.element.value
        const v=this.props.addElement(element);
       
        this.setState(()=>{return {error:v}})
        
    }
    drawIt()
    {
        
        this.props.drawer() //calls drawer function in Final componet
        
    }
    
    render()
    {
        return(
            <div>
            <form onSubmit={this.add}>
                <input type="text" name="element" placeholder="add element here"/>
                <button>Add elements</button>
                {this.state.error && <p>{this.state.error}</p>}
                </form>
                <button onClick={this.drawIt}>DRAW IT</button>
                <p> elements inside Element array</p>
                <ul>
                    {this.props.element.map((x)=>{return <Element key={x} v={x}/>})}
                </ul>
                
            </div>
        )
    }
}


class Drawer extends React.Component{
    render()
    {
        return(
            <div>
            { this.props.draw.length > 0 &&  <p>new randomly generated position of elements </p>}
                <ul> 
                    {this.props.draw.map((x) => { return <Element key={x} v={x} /> })}
                </ul>
            </div>
        )
    }
}
class Element extends React.Component {
    render() {
        return (
            <li>{this.props.v}</li>
        )
    }
}

ReactDOM.render(<Final/>,dom)
&#13;
<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="fn"></div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

那是因为你正在改变状态数组,你可以在drawer方法中克隆或使用结构分配:

错误

var t = this.state.element;

从右

var t = [...this.state.element];

您还可以看到它正常工作here

答案 1 :(得分:0)

在javascript对象中,数组作为参考传递。

基本上就是你的行

var t=this.state.element

这没有制作数组的副本,而是创建了对同一数组的新引用。

var t = [...this.state.element];

使用解构赋值,您可以将数组中的值或对象的属性解压缩为唯一或新变量。