Search code examples
javascriptreactjsreact-routerjsxthemoviedb-api

How to preserve state for component added to an favourite list


I try to preserve state in three global views.

I have component MovieRow which is called in the Popular, Favorite and Search components. The goal is that component MovieRow preserve its state when it is called in this views (Popular ...)

For example, if I have 2 movies I checked one movie to add to favorite this movie should keep state. Now if I add a movie to the favorite list when I click and change the global view the component MovieRow will mount again and resets the state.

I tried many different ways. Store state one global variable with conditional render to my MovieRow and other.

Edit: You could see full code here https://codesandbox.io/s/lpjp0oxmmq

Edit 2 : I success store my state but I can't success to use correctly.

componentWillUnmount () {
    let storeState = localStorage.setItem('someSavedState', JSON.stringify(this.state))
    console.log(" ------------------- unmount ------------------- ")
    console.log(JSON.parse(localStorage.getItem('someSavedState')))
    console.log(" ------------------- ------- ------------------- ")
}

componentWillMount() {
    const rehydrate = JSON.parse(localStorage.getItem('someSavedState'))
    console.log(" ------------------- will mount ------------------- ")
    console.log(rehydrate)
    console.log(" ------------------- ---- ----- ------------------- ")
    // this.setState({isFaved: rehydrate})
}

Have you idea who help me ?

We see the state get lost in this picture. The color of the button who depend on the state has been reset.

View popular with the first movie added to fav

view favorite with fav movie

MoviesRow.js :

import React from 'react'
import '../css/MovieRow.css';
import { APIKEY, baseURL } from '../../App'
import { filter } from '../../View/Popular'

var myFavoriteMovies = []

function IsFav(props) {
    return (
        <div movieId={props.movie.id} className="MovieRow">
        <div>
        <img alt="poster" src={props.posterSrc} />
        </div>
        <div>
        <h3>{props.movie.title}</h3>
        <p>{props.movie.overview}</p>
        <input type="button" value="View"/>

        <button onClick={props.onClick}  className=" heart">
        </button>

        </div>
        </div>
        );
}

function IsNotFav(props) {
    return (
        <div movieId={props.movie.id} className="MovieRow">
        <div>
        <img alt="poster" src={props.posterSrc} />
        </div>
        <div>
        <h3>{props.movie.title}</h3>
        <p>{props.movie.overview}</p>
        <input type="button" value="View"/>

        <button onClick={props.onClick} className="toggled heart">
        </button>

        </div>
        </div>

        );
}

class MovieRow extends React.Component {
    constructor(props) {
        super(props)
        this.addFavorite = this.addFavorite.bind(this)
        this.deleteFavorite = this.deleteFavorite.bind(this)
        this.state = {
            isFaved: false,
        }
    }

    viewMovie() {
        const url = "https://www.themoviedb.org/movie/" + this.props.movie.id
        window.location.href = url
        console.log(this.props.movie.id)
    }

    addFavorite() {
        this.setState({isFaved: true})
        const favMovie = "".concat(baseURL, 'movie/', this.props.movie.id ,'?api_key=', APIKEY) 
        myFavoriteMovies.push(favMovie)
    }

    deleteFavorite() {
        this.setState({isFaved: false})
    }

    render() {
        const isFaved = this.state.isFaved;
        let movie;

        if (isFaved) {
            movie = <IsNotFav  movie={this.props.movie} posterSrc={this.props.posterSrc} onClick={this.deleteFavorite}/>
        } else {
            movie = <IsFav movie={this.props.movie} posterSrc={this.props.posterSrc} onClick={this.addFavorite}/>
        }

        return movie
    }
}
export { MovieRow as default, myFavoriteMovies}

Solution

  • I reworked your original code to provide an example of how to preserve state in your Popular component while traversing routes.

    Please see the link below. Happy coding.

    CodeSandbox link

    enter image description here