2015-06-15 40 views
17

Tôi biết đã có một câu hỏi tương tự nhưng không có mã được chia sẻ trong đó.phản ứng có nguồn gốc this.setState không hoạt động

Dưới navbarChanged()> nếu điều kiện, tôi đang thực hiện this.setState. Đây là loại HomeTab nhưng setState dường như không hoạt động.

Bất kỳ manh mối/con trỏ nào?

class HomeTab extends React.Component { 
    constructor() { 
    super() 

    this.setState({ 
     isNavBarHidden: false 
    }); 
    } 

    updatePosition(lastPosition) { 
    } 

    navbarChanged() { 
    console.log("received navbar changed event", AppStore.navbarVisible()); 

    if (AppStore.navbarVisible()) { 
     StatusBarIOS.setHidden(false) 
     this.setState({ isNavBarHidden: false}) 
     // this.state.isNavbarHidden is still true here 
     this.render(); 
    } 
    else { 
     StatusBarIOS.setHidden(true); 
     this.setState({ isNavBarHidden: true}); 
     this.render(); 
    } 
    } 

    componentDidMount() { 
    AppStore.addNavbarChangeListener(this.navbarChanged.bind(this)); 
    } 

    componentWillMount() { 
    StatusBarIOS.setHidden(false) 
    this.setState({ isNavBarHidden: false }); 
    } 
} 

Và đây là render() mã của tôi:

render() { 
    return (
     <NavigatorIOS style={styles.container} 
      navigationBarHidden={this.state.isNavBarHidden} 
      ref="navigator" 
      initialRoute={{ 
       title: 'Foo', 
       component: HomeScreen, 
       passProps: { parent: this } 
      }} 
     /> 
    ) 
    } 

Trả lời

43

Đừng gọi một cách rõ ràng render. React sẽ tự động làm lại khi trạng thái hoặc đạo cụ thay đổi, vì vậy không cần thiết cho điều này. Ngoài ra, phương pháp render thực tế của bạn là gì?

Đối với vấn đề của bạn tốt, setState không đồng bộ và do đó cố gắng làm việc trực tiếp với nhà nước sau khi cuộc gọi setState không hoạt động vì bản cập nhật nhất thiết sẽ không chạy. Thay vào đó bạn có thể sử dụng đối số thứ hai để setState mà là một callback:

this.setState({ myVal: 'newVal'}, function() { 
    // do something with new state 
}); 

này sẽ được kích hoạt sau khi nhà nước đã được thiết lập và sau khi thành phần đã được tái tạo hình.

+1

Cảm ơn bạn rất nhiều vì câu trả lời của bạn. 'setState' là câu trả lời không đồng bộ câu hỏi này. Tôi đã cập nhật mã của tôi với phương thức render() của tôi. Tôi sẽ loại bỏ render(); những gì bạn đề xuất có ý nghĩa. Tôi vẫn còn bối rối mặc dù tại sao thanh điều hướng của tôi không hiển thị lại (nhưng thanh tiêu đề là). – Abdo

+1

WOW cảm ơn - Tôi không có ý tưởng thậm chí đọc trên và trên các tài liệu setState là không đồng bộ - TỪ TỪ CNTT nhiều tuts trực tuyến nói rằng giao diện người dùng sẽ làm cho sau khi gọi này - nó không ngay lập tức và câu trả lời của bạn đã giúp tôi ồ ạt. Cảm ơn – landed

4

Thay vì setState, hãy sử dụng trạng thái làm thành viên thể hiện của lớp es6. chức năng setState có thể được gọi sau này để đảm bảo các hiển thị lại cần thiết.

constructor() { 
    super() 

    this.state = { 
     isNavBarHidden: false 
    }; 
    } 
0

Bạn cũng có thể cập nhật trạng thái trong eventHandlers và nghe componentWillReceiveProps cho mã mà bạn cần phải chạy sau khi thay đổi trạng thái.

componentWillReceiveProps(nextProps,nextState){ 
    if(this.state.myVar === nextState.myVar){ 
    return; 
    } 
    // TODO perform changes on state change 
} 

Tôi nghĩ rằng nó là nhiều tối ưu hơn so với giải pháp được đưa ra bởi Colin Ramsay trên như tất cả trên logic sẽ chạy trước render được gọi.

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