2016-06-15 21 views
6

Tôi có phương thức handleSelection được gọi khi nhấp vào nút, tuy nhiên, nếu tôi nhấp vào nút khi tiểu bang không được đặt khi nó được đặt thành this.setState({selectedFoods: newSelections});. Mọi thứ khác trong phương thức thực thi một cách chính xác (như các giao diện điều khiển khác nhau của tôi cho tôi biết :)). Khi nút được nhấp lần thứ hai, mọi thứ trong phương thức sẽ được thực hiện lại và công việc setState sẽ hoạt động.React setState không hoạt động trong lần thử đầu tiên, nhưng hoạt động trên giây?

var Flavor = React.createClass({ 
    getInitialState: function() { 
    return { foods: {}, selectedFoods: [], affinities: [] }; 
    }, 
     componentDidMount: function() { 
      $.ajax({ 
       url: this.props.url, 
       dataType: 'json', 
       cache: false, 
       success: function(data) { 
       this.setState({foods: data}); 
       }.bind(this), 
       error: function(xhr, status, err) { 
       console.error(this.props.url, status, err.toString()); 
       }.bind(this) 
      }); 
      }, 
    componentDidUpdate: function() { 
    $('#select-food').selectize({ 
     onChange: this.handleSelection 
     } 
    ); 
    }, 
    handleSelection: function (e) { 
    if (e.target) { 
     var selectedFood = e.target.id; 
    } else { 
     var selectedFood = e; 
    } 
    console.log(selectedFood); 

    if (this.state.foods[selectedFood]) { 
     var selections = this.state.selectedFoods; 
     var newSelections = selections.concat(selectedFood); 
     console.log("newSelections: "+newSelections) 
     var state = Object.assign(this.state, {selectedFoods: newSelections}); 
     this.setState(state); 
     console.log("state: "+this.state.selectedFoods) 
     this.handleAffinities(); 
    } else { 
     console.log("** "+selectedFood+" **"); 
    } 

    }, 
    handleAffinities: function() { 

    console.log("selectedFoods: "+this.state.selectedFoods.length) 
    if (this.state.selectedFoods.length > 0) { 
     var allAffinities = this.state.selectedFoods.map((food) => { 
     return this.state.foods[food]; 
     }); 
     console.log(allAffinities.length); 
     console.log(allAffinities); 

     var commonAffinities = allAffinities[0]; 

     allAffinities.forEach((affinities) => { 
     commonAffinities = commonAffinities.filter((n) => { 
      return affinities.indexOf(n) != -1; 
     }); 
     }) 

     this.setState({affinities: commonAffinities}); 
    } else { 
     this.setState({ affinities: [] }); 
    } 

    }, 
    handleRemove: function(food) { 
    var selectedFoods = this.state.selectedFoods; 
    var index = selectedFoods.indexOf(food); 
    var updatedSelection = selectedFoods.splice(index, 1); 
    this.setState({selectedFoods: selectedFoods}); 
    this.handleAffinities(); 
    }, 

Tại sao mọi thứ thực hiện chính xác lần đầu tiên ngoại trừ chức năng setState? Và tại sao nó hoạt động trên nhấp chuột thứ hai?

+0

Bất kỳ cơ hội nào nếu 'if (this.state.foods [selectedFood])' của bạn không hợp lệ vì một số lý do? có lẽ 'this.state.foods' vẫn còn trống lần đầu tiên hay một cái gì đó như thế? –

+0

Chức năng 'getInitialState' của bạn là gì? Bạn có thể đăng toàn bộ thành phần, có lẽ trong JSFiddle không? –

+0

cảm ơn, tôi đã thêm tất cả mọi thứ vào phương thức hiển thị – exchez

Trả lời

18

Trạng thái đang thay đổi chính xác theo cách được yêu cầu. Vấn đề là các tuyên bố console.log của bạn ngay lập tức sau khi bạn gọi tới số setState đang kích hoạt trước khi cài đặt trạng thái mới.

Từ docs:

setState() không ngay lập tức đột biến this.state nhưng tạo ra một chuyển trạng thái chờ giải quyết. Truy cập this.state sau khi gọi phương thức này có khả năng trả về giá trị hiện tại.

Nếu bạn muốn kích hoạt câu lệnh console.log sau khi quá trình chuyển đổi trạng thái hoàn tất, hãy chuyển hàm như gọi lại setState().

this.setState({selectedFoods: newSelections},() => { 
    console.log(this.state.selectedFoods); 
}); 
+2

điều này thực sự tốt để biết. trạng thái của thành phần của tôi không được cập nhật cũng bằng chứng của DOM không thay đổi như dự định. – exchez

+0

Chỉ cần lưu ý: Tôi đã đấu tranh với một chức năng toggling trong đó tôi cần một cái gì đó như thế này: "Ngay lập tức sau this.setState tôi cần một chức năng để kích hoạt. Tôi giải quyết nó bằng cách chuyển cuộc gọi hàm đó trong callback setState như @Michael nói và Nó đã làm việc tuyệt vời –

+0

Cảm ơn vì điều này! Tôi đã có một nhức đầu của một thời gian cố gắng để con số này ra.Bây giờ tất cả các setState của tôi sử dụng một cuộc gọi lại và tôi không có vấn đề. – Timmo

Các vấn đề liên quan