ReactJS обновляет одно значение в 2D массиве - PullRequest
0 голосов
/ 13 мая 2018

Я пытаюсь обновить одно значение двумерного массива.

Обратите внимание: Я ответил на следующие вопросы

Разница между let a = [] и новым массивом

Многомерный массив Javascript, обновляющий определенный элемент

Javascript: изменить значение ячейки в двумерном массиве

Я использую следующий код для создания 2D-массива

export default function(
    numrows = 16,
    numcols = 10,
    initial = { value: 0, color: 'wheat' },
) {
    let arr = new Array(numrows).fill().map(function() {
        return new Array(numcols).fill(initial);
    });
    return arr;
}

И я использую вышеупомянутую функцию для генерации исходного массива в конструкторе и отображения его в виде таблицы в представлении.

При нажатии кнопки я хочу обновить определенные значения массива, вызвав функцию updateArray.

Проблема, с которой я сталкиваюсь, заключается в том, что функция updateArray обновляет все значения массива до "4" вместо обновления только _gridArray[1][2].value = 4; и _gridArray[0][2].value = 3;

Итак, мой вопрос: как мне обновить только конкретные значения 2D-массива?

Проверьте эту CodeSandbox ссылку для демонстрации приложения

class Main extends Component {
  constructor(props) {
    super(props);
    this.state = {
      gridArray: arrayBuilder() //calls above function
    };
  }

  renderTable = () => {
    return this.state.gridArray.map((data, i) => {
      return <TableRow key={i} row={data} />;
    });
  };

  updateArray = () => {
    let _gridArray = [...this.state.gridArray];
    _gridArray[0][2].value = 3;
    _gridArray[1][2].value = 4;
    this.setState({ gridArray: _gridArray });
  };

  render() {
    return (
      <Fragment>
        <div>
          <button onClick={this.updateArray}>Update Array</button>
        </div>
        <table>
          <tbody>{this.renderTable()}</tbody>
        </table>
      </Fragment>
    );
  }
}

export default Main;

Я также попытался отделить функцию генератора массива и попытался запустить его за пределами проекта. Он обновил значения массива правильно. Пытаться запустите фрагмент кода и проверьте значения в консоли.

function createAndUpdate(){

//1nd method to create 2d array
  
  let arr = new Array(16).fill().map(function() {
 	  return new Array(10).fill(0);
 	});
 	console.table(arr);
 	let newarr = [...arr];
 	newarr[0][2] = 4;
 	console.table(newarr); //value updated properly

//2nd method to create 2d array

 	let arr2 = []
 	for (let i = 0; i < 16; ++i) {
 	  let columns2 = [];
 	  for (let j = 0; j < 10; ++j) {
 	    columns2[j] = 0;
 	  }
 	  arr2[i] = columns2;
 	}
 	console.table(arr2);
 	let newarr2 = [...arr2];
 	newarr2[0][2] = 3;
 	console.table("Updated table");
 	console.table(newarr2); //value updated properly
  }
<h3>Open console and run this snippet</h3>

<button onClick = "createAndUpdate()">Run</button>

1 Ответ

0 голосов
/ 13 мая 2018

Код для обновления массива полностью в порядке, проблема в arrayBuilder.В вашем коде он заполняет массив значением initial, которое является просто ссылкой на объект.Таким образом, массив заканчивается заполнением одним и тем же значением.

Я изменил построитель массива, чтобы клонировать исходный объект для каждой ячейки таблицы, чтобы таблица могла содержать более 1 значения.Остальная часть приложения выглядит хорошо для меня.

export default function(
    numrows = 16,
    numcols = 10,
    initial = { value: 0, color: 'wheat' },
) {
    let arr = new Array(numrows).fill().map(function() {
        return new Array(numcols).fill().map(() => {return {...initial}});
    });
    return arr;
}

Пожалуйста, смотрите соответствующий вопрос SO: Array.prototype.fill () с ссылкой на объект, передает, а не новый экземпляр

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...