I
I
Incold2020-04-18 16:48:41
JavaScript
Incold, 2020-04-18 16:48:41

Why does the value of a two-dimensional array change incorrectly in action?

Recently I started learning React, I'm practicing with a tutorial on the React website (I'm making tic-tac-toe, but using Redux + game parameters are set by the user), and I ran into a problem:
The value in a two-dimensional array (field cell values) changes very strangely, it should change only in one cell, but the value of the entire column (namely, the column)
of the Field Component changes:

class Board extends React.Component {
  componentDidMount() {
    this.props.setSquareValue() // нужно чтобы заполнить все ячейки null значениями
  }

  render() {
    return (
      <div id="board">
        {this.props.squaresValue.map((item , i) =>
          <div className="row" key={`row_${i}`}>
            {item.map((square, j) =>
              <div key={`row_${i}-col_${j}`} className="col p-0">
                <Square location={[i, j]} squareValue={square}/>
              </div>
            )}
          </div>
        )}
      </div>
    );
  }
}

export default connect(
  state => ({
    squaresValue: state.game.squaresValue
  }),
  dispatch => ({
    setSquareValue(num) {
      dispatch(setSquareValue(num));
    }
  })
)(Board);

Cell Component:
function Square (props) {
  return (
    <div className="cell d-flex align-items-center justify-content-center">
      <button className="btn" onClick={()=>{
        props.setSquareValue(props.location, 'X');
      }}>
        {props.squareValue} 
      </button>
    </div>
  );
}

export default connect(
  null,
  dispatch => ({
    setSquareValue(num, value) {
      dispatch(setSquareValue(num, value));
    }
  })
)(Square);

action:
export const setSquareValue = (num, value) => {
  return (dispatch, getState) => {
    if (num === undefined && value === undefined) { 
      let width = getState().gameParameters.fieldWidth;
      let height = getState().gameParameters.fieldHeight;
      return dispatch({ type:'SET_SQUARE_VALUE', values: Array(height).fill(Array(width).fill(null)) });
    }
    else {  // Здесь происходит самое странное
      let array = getState().game.squaresValue; // получаю двумерный массив значений
      console.log(array);  // Здесь почему-то массив уже изменён, хотя значение меняю в следующей строке
Т.е. если поле 3х3, и я нажимаю на ячейку [0,0], то значения поменяют ещё и ячейки [1,0] и [2,0]
      array[num[0]][num[1]] = value; // num (координаты ячейки) приходит нормальный
      return dispatch({ type:'SET_SQUARE_VALUE', values: array });
    }
  }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
0
0xD34F, 2020-04-18
@Incold

values: Array(height).fill(Array(width).fill(null))

The same array is used as elements of the values ​​array. Change to
values: Array.from({ length: height }, () => Array(width).fill(null))

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question