React组件不会对mobx可观察数据做出反应

时间:2017-08-14 18:59:12

标签: reactjs react-native mobx 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 则显示为true。
  4. 在商店方面,在成功/不成功回复后,它会将fetchingListOne设置为false。
  5. 最后在组件方面,由于fetchingListOne设置为false, ActivityIndi​​cator 不应显示,而 ListHeaderComponent 中应显示false。
  6. 但是,这不是发生的事情。这里调用setListOne()方法时,在将fetchingListOne设置为true后,组件不会对api调用后所做的更改做出反应。并且 ActivityIndi​​cator 一直显示并在 ListHeaderComponent 中显示为true。

    我在这里做错了什么?请你帮助我好吗。谢谢

    更新

    我在FlatList之前添加了一个Text组件。在组件类的render方法中添加Text组件或控制台日志记录会使FlatList对更改做出反应。我不知道为什么会发生这种情况。

1 个答案:

答案 0 :(得分:5)

您最常遇到的问题是虽然Flatobserver组件,但FlatList不是(它毕竟是内置组件) )。在此设置_renderFooter中,其他部分由render的{​​{1}}呈现,而不是FlatList呈现。因此,它们不是Flat的生命周期的一部分,而是FlatList的生命周期,因此不会被Mobx跟踪

有两种解决方法,非常简单:

1)将FlatList声明为观察者组件:

_renderItem

2)使用内联匿名_renderItem = observer(({item}) => <Text style={styles.item}>{item.name}</Text> ); 组件:

Observer