2015-02-13 4 views
3

Я использую React.js для динамического создания таблицы html, содержащей текстовые поля. У меня есть строки, которые можно удалить нажатием кнопки. Я ожидаю, когда я нажму «удалить» в первой строке, которую удаляет таблица с удалением строки 1. Однако, когда реакция повторно рисует таблицу, похоже, что она всегда удаляет последнюю строку таблицы из DOM вместо использования фактических значений из моего объекта state. Возможно, я нашел ошибку? Вот мой код:Таблица React.js: удалить кнопку строки визуально удаляет неправильную строку

/** @jsx React.DOM */ 

var MyApp = React.createClass({ 
    getInitialState: function() { 
     return { 
     col_one: ['c1r1', 'c1r2', 'c1r3'], 
     col_two: ['c2r1', 'c1r2', 'c1r3'], 
     col_three: ['c3r1', 'c3r2', 'c3r3'] 
     } 
    }, 
    handleCellChange: function (colName, index, e) { 
     console.log('onChange:', colName, index, e.target.value); 
    }, 
    handleRemove: function (i) { 
     var that = this; 
     console.log('removing row:',i); 
     _.forEach(this.state, function (val, colName) { 
     that.state[colName].splice(i,1); // BUG??? 
     //_.pullAt(that.state[key], i); // doesn't work either 
     }); 
     console.log(this.state); 
     this.setState(this.state); 

    }, 
    render: function() { 
     var that = this, 
     rows = [], 
     cols = _.keys(this.state); 

     rows.push(
     <tr> 
     {cols.map(function (col) { 
     return (
      <th>{col}</th> 
     ) 
     })} 
     </tr> 
    ) 
     for (var i = 0; i < this.state[cols[0]].length; i++) { 
     rows.push(
      <tr> 
      {cols.map(function (col) { 
       return (
       <td> 
        <input type="text" defaultValue={that.state[col][i]} onChange={that.handleCellChange.bind(that, col, i)} /> 
       </td> 
      ) 
      })} 
      <td> 
       <button onClick={this.handleRemove.bind(this, i)}>Remove</button> 
      </td> 
      </tr> 
     ) 
     } 

     return (
     <table> 
      <tbody> 
      {rows} 
      </tbody> 
     </table> 
    ); 
    } 
}); 

React.renderComponent(<MyApp />, document.body); 

seen here as a JSBin

+0

проверьте это htt p: //stackoverflow.com/questions/28258517/react-js-input-element-renders-differently-compared-to-other-elements – Dhiraj

ответ

6

Вы используете defaultValue - что делает вход uncontrolled component, который получает начальное значение, установленное, но чье отображаемое значение никогда не прикоснулся снова Реагировать, если вы не взрывать все (например, с изменением key на нем или предком), и он должен воссоздать его с нуля.

Именно поэтому вы не видите, что отображается новое defaultValue - поскольку в каждой строке нет уникальных ключей, React находит, что на повторном рендеринге есть еще одна строка, и удаляет последнюю строку из реальной DOM, но любые новые defaultValue для входов в нераспределенной строке не имеет никакого эффекта ..

Вот тот же самый код, но с использованием value, что делает его controlled component, который отражает новый value он получает на пересборку:

http://jsbin.com/hacitidaqe/1/

+0

Спасибо, это именно то, что мне нужно! –

+0

Я потратил час или около того, чтобы узнать, почему моя новая пустая строка, которая добавлена, содержит неправильные данные внутри. Данные в 'this.state' не были отражены DOM. Теперь я знаю, почему. Благодарю. – NeverEndingQueue