2016-08-19 4 views
0

Я прихожу из Angular 1.x и надеется обновить неупорядоченный список с помощью React/Redux.Обновление массива в реактиве

В console.log, я вижу, что массив обновляется, но, похоже, он не привязан к DOM. У меня есть следующее:

onKeyPress ввода, у меня есть функция, которая толкает массив сообщений.

<ul className="list-inline"> 
    {messages.map(function(message, key){ 
    return (
     <li key={key} message={message}>{message}</li> 
    ); 
    })} 
</ul> 

Update У меня следующее (но не повезло еще) Некоторые примечания. Я использую Firebase для прослушивания событий и добавления в массив. Хотите узнать, связана ли проблема с привязкой? -

class Comments extends React.Component { 
    constructor(props, context) { 
    super(props, context); 
    this.state = {messages: this.props.messages}; 
    } 

    componentDidMount() { 
    const path = '/comments/all'; 
    // Firebase watches for new comments 
    firebase 
     .database() 
     .ref(path) 
     .on('child_added', (dataSnapshot) => { 
      this.state.messages.push(dataSnapshot.val()); 
      this.setState({ 
      messages: this.state.messages 
      }); 
      //console.log(dataSnapshot.val()); 
     }); 
    } 

    render() { 
    const messages = this.state.messages; 
    return (
     <ul className="list-inline"> 
     {messages.map(function(message, key){ 
      <li key={key}>{message}</li> 
     })} 
     </ul> 
    ); 
    } 
} 
+0

FYI, ваш [принятый в настоящее время ответ] (https://stackoverflow.com/a/39044375/157247) неверен. –

ответ

0

Вам нужны сообщения, которые необходимо установить в компонентах state.

getInitialState() { 
    return { 
    messages: [] 
    } 
} 

Затем в функции установите состояние:

this.setState({messages: updatedMessages}) 

, а затем карту за состоянием сообщений, или переменную messages в render:

const messages = this.state.messages; 


<ul className="list-inline"> 
    {messages.map(function(message, key){ 
etc... 
+0

Этот вызов 'setState' небезопасен для сценария OP, потому что он обновляет состояние на основе существующего состояния (добавляя в массив' messages' состояния). При обновлении состояния на основе существующего состояния вы должны * использовать форму обратного вызова 'setState', потому что обновления состояния являются асинхронными и могут быть объединены. Подробности: https://facebook.github.io/react/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous –

0

Два вопроса:

  1. Вы не d прямое изменение состояния объекта в React. Вместо этого предоставите новый массив через setState с новой записью в нем.
  2. При обновлении состояния на основе существующего состояния вы должны использовать функцию обратного вызова функции setState, а не версию, принимающую объект, поскольку обновления состояния являются асинхронными и могут быть объединены. Использование версии объекта часто срабатывает, но это не гарантируется; действительно, это гарантировано не, в какой-то момент.

Подробнее в документации React: Using State Correctly («Не Modify государства Непосредственно» и «государство обновление может быть Асинхронной» секция).

Так, в обработчике события:

.on('child_added', (dataSnapshot) => { 
    this.setState(state => ({ 
     messages: [...state.messages, dataSnapshot.val()] 
    })); 
    //console.log(dataSnapshot.val()); 
}); 

(Нам нужно () вокруг инициализатора объекта, потому что в противном случае {, казалось бы запустить полное тело функции вместо краткого тела выражения.)