簡體   English   中英

React 是 setstate 弄亂了我的算法?

[英]React is setstate messing up my algorithm?

我是新來的,並且已經實現了一個簡單的視覺選擇排序。 每當單擊按鈕時,我都會運行選擇排序。 根據我的理解,整個算法應該可以運行,並且可以一鍵對數據進行排序。 但是,需要多次單擊按鈕才能對整個數據進行排序。 我假設這是由於在我的函數調用中反應更新狀態並呈現新組件以進行選擇排序。

任何幫助深表感謝 !

class Square extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: null,
            heightSet: 3,
            sorted: false,
        };
    }
  render() {
    var myheight = this.props.heightSet + 'em';
    var sort = this.props.sorted;
    var bgcolor = 'grey';
    var key = this.props.value;
      if (sort){
          bgcolor = 'green';
      }
      else{
          bgcolor = 'grey';
      }
    var divHeightStyle = {
    height: myheight,
    backgroundColor: bgcolor,
    };
    return (
      <div
        id={this.props.value}
        value={this.props.heightSet}
        style={divHeightStyle}
        className="square">
        {this.props.value}
      </div>
    );
  }
}

class Rectangle extends React.Component {
    constructor(props){
        super(props);
    };





    render(){
        return (
            <button
                className="rectangle"
                onClick={() => this.props.selectionSort()} >
            </button>
        )

    }
}

class Board extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            squares: [],
            sorted: [],
        };
        const min = 1;
        const max = 80;
        const rand1 = min + Math.random() * (max - min)
        const rand2 = min + Math.random() * (max - min)
        const rand3 = min + Math.random() * (max - min)
        const maxbars = 50;
        for(let i=0; i<maxbars; i++){
            let rand = min + Math.random() * (max - min)
            this.state.squares[i] = rand;
            this.state.sorted[i] = false;
        }

    }
  renderSquare(i, y, z) {
    return <Square value={i} heightSet={y} sorted={z}/>;
  }


    selectionSort(){
        let i, j, min_idx;
        let finished = 0;
        for(let i=0; i<11; i++)
        {
            min_idx = i;
            for(let j=i+1; j < 12; j++)
            {
                if(this.state.squares[j] < this.state.squares[min_idx])
                {
                    min_idx = j;
                    let temp = this.state.squares[min_idx];
                    this.state.squares[min_idx] = this.state.squares[i];
                    this.state.squares[i] = temp;

                    this.state.sorted[finished] = true;
                    finished++;
                    this.setState({ squares: this.state.squares
                                  })
                    this.setState({ sorted: this.state.sorted

                    })
                }
            }

        }

    }

    renderRectangle() {
        return <Rectangle
        selectionSort={this.selectionSort.bind(this)}
        />;
    }

    render() {
    const status = '';

    return (
      <div>
        <div className="rec-wrapper">
        {this.renderRectangle()}
        </div>
        <div className="status">{status}</div>
        <div className="board-row">
          <div className="square-wrapper">
          {this.renderSquare(1,this.state.squares[0],this.state.sorted[0])}
          {this.renderSquare(2,this.state.squares[1],this.state.sorted[1])}
          {this.renderSquare(3,this.state.squares[2],this.state.sorted[2])}
          {this.renderSquare(4,this.state.squares[3],this.state.sorted[3])}
          {this.renderSquare(5,this.state.squares[4],this.state.sorted[4])}
          {this.renderSquare(6,this.state.squares[5],this.state.sorted[5])}
          {this.renderSquare(7,this.state.squares[6],this.state.sorted[6])}
          {this.renderSquare(8,this.state.squares[7],this.state.sorted[7])}
          {this.renderSquare(9,this.state.squares[8],this.state.sorted[8])}
          {this.renderSquare(10,this.state.squares[9],this.state.sorted[9])}
          {this.renderSquare(11,this.state.squares[10],this.state.sorted[10])}
          {this.renderSquare(12,this.state.squares[11],this.state.sorted[11])}
          </div>
        </div>
      </div>
    );
  }
}

你直接改變狀態,你不應該這樣做。

this.state.squares[i] = rand;
this.state.sorted[i] = false;

應該

const squares = [...this.state.squares];
squares[i] = rand;

const sorted = [...this.state.sorted];
sorted[i] = false;

this.setState({
  squares: squares,
  sorted: sorted  
});

React 的setState 運行 async ,因此在循環中設置它會給你意想不到的結果。

在循環運行完成后,您只需要調用一次setState

selectionSort(){
    let i, j, min_idx;
    let finished = 0;
    let squareResult = [...this.state.squares];
    let stortedResult = [...this.state.sorted]

    for(let i=0; i<11; i++)
    {
        min_idx = i;
        for(let j=i+1; j < 12; j++)
        {
            if(squareResult[j] < squareResult[min_idx])
            {
                min_idx = j;
                let temp = squareResult[min_idx];
                squareResult[min_idx] = squareResult[i];
                squareResult[i] = temp;

                sortedResult[finished] = true;
                finished++;                
            }
        }
        this.setState({ squares: squareResult, sorted: sortedResult })                
    }

}

我同意詹姆斯的意圖。 也許可以通過將 setState 方法更改為

this.setState({ squares: [...squareResult], sorted:[...sortedResult]})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM