本机反应:运行微调器直到ListView渲染

时间:2016-09-13 09:08:53

标签: firebase react-native promise firebase-realtime-database

在我的应用中,我从Firebase中提取数据并在ListView中呈现它们。我希望微调器一直运行,直到整个列表出现。

我添加了一个带有条件的视图,该条件显示state.loading是否为'true',但如果我在componentDidMount中更改它,则函数不起作用,因为列表尚未显示

这是我的代码:

module.exports = React.createClass({
 getInitialState() {
return({
  loading: false,
  displayName: '',
  title: '',
  dataSource: ds.cloneWithRows([{
    title: '',
    author: ''
  }])
  })
},

componentDidMount() {
let user = firebaseApp.auth().currentUser;

if (!user.displayName) {
  this.props.navigator.push({
    name: 'chooseName'
  })
} else {
  // proceed normally with application
  this.setState({
    displayName: user.displayName
  })

  this.listenForItems(topicsRef);
 }

},

 listenForItems(ref) {
   ref.on('value', (snap) => {
  let topics = [];
  snap.forEach(topic => {
    topics.push({
      title: topic.val().title,
      author: topic.val().author,
        key: topic.key
    })
   })
  this.setState({dataSource: ds.cloneWithRows(topics)});
   })
  },

  signOut() {
// sign out the user
firebaseApp.auth().signOut()
  .then(() => {
    // Sign out successful
    this.props.navigator.popToTop();
  }, (error) => {
    console.log(error);
  })
},

details(data) {
this.props.navigator.push({
  name: 'topicDetail',
  displayName: this.state.displayName,

  title: data.title,
  author: data.author,

  row_uid: data.key
})
},

 renderRow(rowData) {
return (
  <TouchableOpacity style={styles.row}
    onPress={() => this.details(rowData)}
  >
    <Text style={styles.rowTitle}>
      {rowData.title}
    </Text>
    <Text>
      {rowData.author}
    </Text>
  </TouchableOpacity>
)

},

addTopic() {
topicsRef.push({
  title: this.state.title,
  author: this.state.displayName
})
},

render() {
if (this.state.loading) {
  return (
    <Container style={styles.containerSignIn}>
     <Content>
         <Spinner />

     </Content>
 </Container>);
}
return (
  <View style={styles.flexContainer}>
    <View style={styles.header}>
      <TouchableOpacity
        onPress={() => this.signOut()}
      >
        <Text style={styles.link}>
          Sign out
        </Text>
      </TouchableOpacity>
      <Text style={styles.title}>
        {this.state.displayName}
      </Text>
    </View>
    <View style={styles.body}>
      <TextInput
        placeholder='Something on your mind?'
        style={styles.input}
        onChangeText={(text) => this.setState({title: text})}
        onEndEditing={() => this.addTopic()}
      />
      <ListView
        style={styles.list}
        enableEmptySections={true}
        dataSource={this.state.dataSource}
        renderRow={(rowData) => this.renderRow(rowData)}
      />
    </View>
  </View>
  )
}
});

1 个答案:

答案 0 :(得分:1)

我假设您的Spinner组件有效。

由于您的反应生命周期中可能存在的问题,我可以在第一次运行中推荐:

1。)如果你希望你的Spinner在你的View显示时处于活动状态,在定义你的initialState时将state.loading设置为true。

getInitialState() {
    return({
        loading: true,
        ...
    })
}

2。)更改firebase请求的(成功)Promise回调中的加载状态,而不是componentDidMount()中的加载状态。

listenForItems(ref) {
    ref.on('value', (snap) => {
        ...
        this.setState({
            loading: false,
            dataSource: ds.cloneWithRows(topics)
        });
    })
}

希望有所帮助。