2017-08-14 65 views
4

我正在使用mobX爲我的反應原生項目。請考慮這家店類:React組件不響應mobx可觀察數據

class Birds { 
    @observable listOne = []; 
    @observable fetchingListOne = false; 
    @observable fetchErrorOne = ''; 

    @action setListOne =() => { 
     this.fetchingListOne = true; 
     api.getList() 
      .then((data) => { 
       this.listOne.replace(data); 
       this.fetchingListOne = false; 
      }) 
      .catch((error) => { 
       this.fetchingListOne = false; 
       this.fetchErrorOne = error; 
      }); 
    }; 
} 

而且這個反應成分:

@inject('BirdStore') @observer 
export default class Flat extends React.Component { 
    componentDidMount() { 
     this.props.BirdStore.setListOne(); 
    } 

    _renderHeader =() => { 
     return <Text style={styles.listHeaderText}> 
      Hello {this.props.BirdStore.listOne.length} is {this.props.BirdStore.fetchingListOne.toString()} 
      </Text>; 
    }; 

    _renderItem = ({item}) => { 
     return <Text style={styles.item}>{item.name}</Text> 
    }; 

    _renderFooter =() => { 
     if (this.props.BirdStore.fetchingListOne) { 
      return <ActivityIndicator/> 
     } 
     else { 
      return null 
     } 
    }; 

    render() { 
     const dataSource = this.props.BirdStore.listOne.slice(); 

     return (
       <View style={styles.container}> 
        <Text>Fetching: {this.props.BirdStore.fetchingListOne.toString()}</Text> 
        <FlatList 
         style={styles.listContainer} 
         ListHeaderComponent={this._renderHeader} 
         data={dataSource} 
         renderItem={this._renderItem} 
         keyExtractor={(item, i) => item.id} 
         ListFooterComponent={this._renderFooter} 
        /> 
       </View> 
     ) 
    } 
} 

從上面看起來對我說:

  1. Flat組件坐騎,它調用該方法的店面setListOne()
  2. setListOne()fetchingListOne設置爲true並進行api調用。
  3. 在組件側,當fetchingListOne爲真時,ActivityIndi​​cator顯示器,以及在ListHeaderComponent它應該顯示真實的。
  4. 在商店方面,成功/不成功的迴應後,它將fetchingListOne設置爲false。
  5. 最後上的元件側,因爲fetchingListOne被設置爲假,ActivityIndi​​cator不應顯示和在ListHeaderComponent它應該顯示假。

但是,這不是發生了什麼事情。在調用setListOne()方法時,在將fetchingListOne設置爲true後,該組件不會對api調用後所做的更改作出反應。而ActivityIndi​​cator不斷顯示,並在ListHeaderComponent其顯示爲真。

我在這裏做錯了什麼?你可以幫我嗎。謝謝

更新

我已在FlatList前添加一個文本組件。在組件類的render方法中添加一個Text組件或控制檯日誌記錄會使FlatList對這些更改做出反應。我不知道爲什麼會發生這種情況。

+0

你能嘗試使用'mobx.useStrict()',看看是否能解決您的問題?這意味着使用getters和setter來獲得可觀察值,特別是'fetchingListOne' –

+0

@ChristopherChiche我試着將'mobx.useStrict(true)'放在** Birds **類所在的store.js中。但是那給了我一個錯誤:* ...如果這個改變是有意的,請把代碼包裝在一個'action'中。試圖修改:[email protected]] *。所以我把'useStrict();'放在'@action setListOne'中。它不會拋出任何錯誤,但它有同樣的問題; ** FlatList **組件不會像它們應該那樣對這些更改做出反應。 –

回答

2

這裏最可能遇到的問題是,雖然Flatobserver組件,但FlatList不是(它畢竟是內置組件)。在這個設置_renderFooter和其他部分是renderFlatList,但不是FlatList。因此,他們是不平坦的生命週期的一部分,但FlatList的,因此不被Mobx跟蹤

有兩種方法來解決這個問題,既很簡單:

1)申報_renderItem作爲觀察員部分:

_renderItem = observer(({item}) => 
    <Text style={styles.item}>{item.name}</Text> 
); 

2)使用內聯匿名Observer組件:

_renderItem = ({item}) => 
    <Observer>{ 
     () => <Text style={styles.item}>{item.name}</Text>} 
    </Observer> 
+0

是的,我認爲這是問題所在,因爲我在FlatList上面添加了一個** Text **組件,並且它對變化做出了反應,*此外,這使得整個FlatList完美工作*(更新代碼請看看在類的渲染方法)。無論如何,第一個方法給出了一個錯誤,[TypeError:不能作爲函數調用類]。第二種方法基本上做同樣的事情;它在提取後會渲染所有列表。 –

相關問題