2015-08-13 3 views
2

Я не могу понять, что я здесь делаю неправильно. У меня есть событие, которое запускает функцию для изменения состояния нескольких значений, чтобы я мог отключить вызов API; однако при первом запуске функции состояния не изменяются. Во второй раз функция запускает изменение состояния от предыдущего прогона. Что может вызвать эту задержку?Состояние не обновляется мгновенно ReactJS

Как вы можете видеть ниже, handleFilterChange принимает значения из события, и я могу проверить правильность получения значений; однако, если я проверю значение состояния сразу после установки, я вижу, что он не определен. Когда событие приходит во второй раз; однако я вижу, что первоначальное изменение состояния произошло, но второго нет. Итак, почему setState нужно вызывать дважды, чтобы фактически установить состояние?

var GridView = React.createClass({ 
    getInitialState: function() { 
    window.addEventListener("scroll", this.handleScroll); 
    return { 
     data: [], 
     page: 0,  //for pagination 
     loadingFlag: false, 
    }; 
    }, 

    getMainFeed: function() { 

... 

}, //end function 
getFilteredItems: function() { 
    ... 

}, //end function 
    componentWillMount: function() { 

    }, 
    listenForFilterChange: function() { 
    window.addEventListener("selectedFilterChange", this.handleFilterChange, false); 
    }, 
    componentWillUnmount: function() { 
    window.removeEventListener("selectedFilterChange", this.handleFilterChange, false); 
    }, 
    handleFilterChange: function(filter) { 
    //alert(filter.detail.filterType); 
    //Convert Data for getFilteredItems 
    //(EventType, Category, Buy, Inspiration) { 
    switch (filter.detail.filterType) { 
    //alert(filter.detail.filterType); 
    case 'category': 
     this.setState({ 
     itemCategory: filter.detail.filterSelected, 
     }); 
     break; 
    case 'event': 
     this.setState({ 
     eventType: filter.detail.filterSelected, 
     }); 
     break; 
    case 'type': 
     if (0){ 
     this.setState({ 
      filterBuy: 1, 
      filterInspiration: 0, 
     }); 
     } 
     if (1){ 
     this.setState({ 
      filterBuy: 0, 
      filterInspiration: 1, 
     }); 
     } 
     if (2){ 
     this.setState({ 
      filterBuy: 1, 
      filterInspiration: 1, 
     }); 
     } 
     break; 
    case 'trending': 
     this.setState({ 
     itemCategory: filter.detail.filterSelected, 
     }); 
     break; 
    } 

    this.getFilteredItems(); 
}, 
    componentDidMount: function() { 
    this.listenForFilterChange(); 
... 
    }, 
    handleScroll:function(e){ 
... 
    }, 
    componentDidUpdate: function() { 
... 
    }, 
    render: function() { 
     return (
     <div id="feed-container-inner"> 
      <GridMain data={this.state.data} /> 
     </div> 

    ); 
    } 
    }); 

ответ

2

setState асинхронный, так что изменения не будете отражаться в состоянии сразу:

SetState() не сразу мутировать this.state но создает в ожидании переход государства. Доступ к this.state после вызова этого метода может потенциально вернуть существующее значение.

Если вам необходимо подтвердить состояние или выполнить логику на основе изменения состояния, используйте аргумент обратного вызова, как описано here.

+0

Спасибо, @ Дэвид. Я этого не понимал, теперь это имеет гораздо больше смысла. –

0

setState не нужно вызывать дважды. Чтение кода я не могу вывести, что не так точно, но я могу посоветовать следующее:

  1. console.log ваше состояние в оказывают функцию, если вы хотите знать, что в нем.
  2. Еще раз проверьте, что в вашем случае (какой случай срабатывает, и если он действительно срабатывает). 3. Проверьте, не выполняет ли другая функция (другое setState) переопределение состояния, которое вы хотите установить в handlefilterChange.

Моя ставка является то, что ваш фильтр не получает правильные значения, первый прием неопределенную filter.detail.filterSelected потом еще один определенный ... Проверьте, что в filter.detail.filterSelected я вижу в комментарии вы только проверено на filter.detail.filterType

В любом случае ваша проблема связана не с установкой setState, а с вашими данными. Я уверен.

Позвольте мне знать, если это помогло

+0

François, я уже выполнил эти проверки, оказалось, что проблема в том, что 'setState' является асинхронным, поэтому я должен использовать функцию обратного вызова. В очередной раз благодарим за помощь. –

+0

ОК, console.log в рендере бы сработал, но ответ Билла Уолтерса дает причину и является более точным. –

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

  • Нет связанных вопросов^_^