Skip to content

React component does not react to mobx observable data #15507

Closed
@Benjamin5050

Description

@Benjamin5050

I am using mobX for my react native project. Please consider this store class:

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;
            });
    };
}

And this is the react component:

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

    _renderHeader = () => {
        return <Text style={styles.listHeaderText}>Fetching 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}>
                    <FlatList
                        style={styles.listContainer}
                        ListHeaderComponent={this._renderHeader}
                        data={dataSource}
                        renderItem={this._renderItem}
                        keyExtractor={(item, i) => item.id}
                        ListFooterComponent={this._renderFooter}
                    />
                </View>
        )
    }
}

From above it looks to me that:

  1. When the Flat component mounts, it calls the method of the store setListOne().

  2. setListOne() sets fetchingListOne to true and makes an API call.

  3. On the component side, when the fetchingListOne is true, the ActivityIndicator displays, and in the ListHeaderComponent it should display true.

  4. On the store side, after a successful/unsuccessful response, it sets fetchingListOne to false.

  5. Finally on the component side, because fetchingListOne is set to false, ActivityIndicator should not display and in the ListHeaderComponent it should display false.

However, this is not what's happening. Here, when the setListOne() method is called after it sets the fetchingListOne to true, the component does not react to the changes made after API call. And the ActivityIndicator keeps displaying and in ListHeaderComponent it's displaying true.

What am I doing wrong here? Could you please help me. Thank you

I am using:

  • "react": "16.0.0-alpha.12",
  • "react-native": "^0.46.1",
  • "react-navigation": "^1.0.0-beta.11"

Metadata

Metadata

Assignees

No one assigned

    Labels

    Ran CommandsOne of our bots successfully processed a command.Resolution: LockedThis issue was locked by the bot.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions