alfredopacino
alfredopacino

Reputation: 3241

Re-render on state change

I'm struggling trying to re-render the component BookmarkButton on click on its icon. Basically, here the scenario. An Item could be bookmarked or not. I use BookmarkButton to add/remove item from the bookmarks I want to update the render of BookmarkButton to show a star icon (item is bookmarked) or just the outline (item isn't bookmarked). Very common scenario indeed. The problem is BookmarkButton doesn't re-render on state change..

Item component

class Item extends Component {
    static navigationOptions = ({ navigation,state }) => ({
        headerTitle: "",
        headerTintColor: 'white',
        headerRight: <RightSide navigation={navigation} /> ,
    })
    constructor(props) {
        super(props);
    }

RightSide component

class RightSide extends Component {

    render(){
        const { navigation } = this.props;
        const { params } = navigation.state;

        return  (
            <View style={{flex:1,flexDirection:"row"}}>
                <BookmarkButton id={params.id} />
            </View>
        )

    }
}

BookmarkButton component

 class BookmarkButton extends Component {

        constructor(props)  {
            super(props);
            this.state = {
                bookmarked: false
            }
        }
        async componentDidMount(){
        let c = await this.checkBookMark(this.props.id)
        await this.promisedSetState({bookmarked: c})
    }

        async _toggleBookmark(id) {

            let b = await this.checkBookMark(id) //check if the ID is present in bookmarks @returns boolean
                b ? await this.removeBookMark(id) : await this.addBookMark(id)
            this.setState({bookmarked:b})
        }
        promisedSetState = (newState) => {
        return new Promise((resolve) => {
            this.setState(newState, () => {
                resolve()
            });
        });
    };
        render () {

            let icon = this.state.bookmarked ? "md-star" : "md-star-outline"
            return(
                <TouchableOpacity
                    onPress={() => this._toggleBookmark(this.props.id)}
                    <Ionicons name={icon} color="white" size={30} />
                </TouchableOpacity>
            )}

Upvotes: 0

Views: 152

Answers (1)

Andrew
Andrew

Reputation: 28539

I think I know what your issue is.

You are checking to see if an item has been bookmarked before. I imagine that if it hasn't been booked marked this.checkBookMark(id) will return false. Meaning b === false

If it returns false then you will add it to the bookmarked list using await this.addBookMark(id)

However, this is the important part. You are then setting the state to the value of b, which is false. You should be setting the value of the state to !b

Your setState should become

this.setState({bookmarked: !b})

Upvotes: 1

Related Questions