2015-12-04 2 views
-1

Я создаю построитель страниц с помощью React.ReactJs - Как обновить состояние в массиве?

У меня есть компонент, который содержит структуру страницы.

var LayoutPage = React.createClass({ 

getInitialState: function getInitialState() { 
    return { 
     items: { 
      '78919613':{ 
       id: '78919613', 
       component : 'OneColumn', 
       cols:{ 
        '565920458':{ 
         id: '565920458', 
         content:{ 
          '788062489':{ 
           id: '788062489', 
           component : 'Text', 
           params: 'Lorem ipsum' 
          }, 
          '640002213':{ 
           id: '640002213', 
           component : 'Text', 
           params: 'Lorem ipsum' 
          } 
         } 
        } 
       } 
      } 
     } 
    }; 
}, 
..... 
}); 

У меня есть система с drag'n drop, чтобы добавить новый элемент на странице, и он работает. Но когда новый элемент удален, я хочу обновить состояние, чтобы добавить новый элемент в массив.

Так как я могу нажать новый предмет? Я сделал тест с этим:

this.state.items.push({.....}); 

Но у меня есть ошибка:

TypeError: this.state.items.push is not a function 

Можете ли вы мне помочь?

спасибо.

+1

Потому что 'this.state.item' это' object' не массив! –

+0

Да, спасибо, спасибо. Так как я могу сделать с объектом? – anardil

ответ

1

Вы начнете получать головные боли, если вы непосредственно мутировать состояние вашего приложения. Если вы забудете позвонить this.setState, то он не будет повторно рендеринга!

Предполагая, что вы не можете использовать массив (что было бы проще), вам нужно будет сгенерировать уникальный ключ, если вы хотите добавить другой объект к объекту.

// create a new copy of items based on the current state 
var newItems = Object.assign({}, this.state.items), 
    newItem = { id: '', component: '', cols: {} }, 
    uniqueId = generateUniqueId(); 

// safely mutate the copy 
newItems[uniqueId] = newItem; 

// update the items property in state 
this.setState({ items: newItems }); 

Это еще проще с ES7/Babel.

const newItem = { id: '', component: '', cols: {} }, 
     uniqueId = generateUniqueId(), 
     items = { [uniqueId]: newItem, ...this.state.items }; 

this.setState({ items }); 

Вы можете создать аналогичный уникальный идентификатор, который вы уже там с помощью Math.random.

function generateUniqueId() { 
    // removing leading '0.' from number 
    return Math.random() 
    .toString() 
    .slice(3); 
} 
+0

Спасибо @ Dan Prince. Оно работает. Итак, для вас это не лучшее решение для прямого изменения состояния? – anardil

+0

НИКОГДА не мутируйте 'this.state' напрямую, так как вызов' setState() 'впоследствии может заменить мутацию, которую вы сделали. Относитесь к 'this.state', как если бы он был неизменным. - [из React docs] (https://facebook.github.io/react/docs/component-api.html#setstate) –

2

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

this.state = { 
     items: [ // items array 
     { 
      id: 1, 
      name: "Stack" 
     }, 
     { 
      id: 2, 
      name: "Overflow" 
     }], 
     count: 3, // another state 
     textValue : '' // and this is state too 
    } 

Где элементы это массив объектов. И тогда вы сможете добавлять новые элементы в массив.

const newItem = { 
    id : this.state.count, 
    name: this.state.textValue 
}; 
const newArr = this.state.items.concat(newItem); 
this.setState({ 
    items: newArr, 
    textValue: '', 
    count: this.state.count + 1 
}) 

Весь пример here.

Я надеюсь, что это вам поможет!

Благодаря

+0

На самом деле мои позиции - формат JSON. – anardil

+0

Вы должны проанализировать его с помощью метода 'JSON.parse (obj)'. с ним будет легче работать –

Смежные вопросы