8

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}
crg
  • 4,284
  • 2
  • 29
  • 57
  • 1
    You could try declaring the `myFavoriteMovies` array in `Favorite` and passing it to `MovieRow` as a prop. Of course you would then need to pass `toggleFavorite` (bound to `Favorite`) as a prop as well. By moving state upwards like this, you can guarantee that `Favorite` will be sensitive to the state change and rerender accordingly. – Parabolord Jul 14 '18 at 16:28
  • Yes but all of my views (I have three global component `Popular` `Search` `Favorite`) All of this components displayed movies with `MovieRow`. I must display the favourite state in all global component. If I do your idea I having state up to date in `Favorite` global component and not in other like `Search` or `Popular` or in future components – crg Jul 14 '18 at 17:13

1 Answers1

5

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

Cesar N Mejia Leiva
  • 1,611
  • 1
  • 12
  • 18
  • Great, thank you @CesarNapoleonMejiaLeiva. I had a bad begin. I restart with brain wave of your code. – crg Jul 20 '18 at 07:55