I'm attempting to filter state using multiple checkboxes.
I have it working to some degree, in that you can check one genre to filter the movies by that genre.
I'm struggling to 'restore state' after the checkbox is unchecked, and to also allow for multiple filters to be selected.
I've tried cloning the original state using json.stringify and also clonedeep as suggested in some of the other stackoverflow questions, but this doesn't seem to work for me and some say it's a bad way to do it all together.
I've created a stackblitz of the current state of the app here:
If anyone can point me in the right direction I would be really grateful. Even if it's just a link to a decent article or tutorial that would be super helpful. This munity has saved my butt lately learning this stuff!
I'm attempting to filter state using multiple checkboxes.
I have it working to some degree, in that you can check one genre to filter the movies by that genre.
I'm struggling to 'restore state' after the checkbox is unchecked, and to also allow for multiple filters to be selected.
I've tried cloning the original state using json.stringify and also clonedeep as suggested in some of the other stackoverflow questions, but this doesn't seem to work for me and some say it's a bad way to do it all together.
I've created a stackblitz of the current state of the app here:
https://stackblitz./edit/react-9t8f6e
If anyone can point me in the right direction I would be really grateful. Even if it's just a link to a decent article or tutorial that would be super helpful. This munity has saved my butt lately learning this stuff!
Share Improve this question asked Jan 30, 2019 at 7:51 Stephanie ParkerStephanie Parker 4011 gold badge8 silver badges19 bronze badges 6- You really should try to include in the post itself all the information needed to help you. Now the important bits are behind a link. – Sami Hult Commented Jan 30, 2019 at 7:58
- @SamiHult apologies - last time I posted a question everyone was asking me to put it on stackblitz so thought it would be more helpful if I did it first this time around. – Stephanie Parker Commented Jan 30, 2019 at 8:00
- check this once, stackoverflow./questions/38133137/… , it may help you – Jayavel Commented Jan 30, 2019 at 8:04
-
1
@Sparker Parker you are doing it wrong way. You should get all movies data and store into the state is another variable
allMovies
and then when checkbox is changed you should get allcheckboxes
and filter according to them. But keep all themovies
in one seperate state variable – Maheer Ali Commented Jan 30, 2019 at 8:04 - are you looking for a solution like this stackblitz./edit/react-cbkfx4 ? – Jayavel Commented Jan 30, 2019 at 8:08
2 Answers
Reset to default 3Either you can go with previous answer or you can also do like below:
First option : Keep your all data's in two states like movies
and defaultData
state
For filter and remove/cancel use movies
and for revert back to all movies use defaultData
and in your example you have used ponentWillMount to fetch data, use ponentDidMount instead
// Fire API on init
ponentDidMount() {
// Fetch Genre Data
axios.get(`${base_url}genre/movie/list?api_key=${api_key}`)
.then(res => this.setState({ genres: res.data.genres }));
// Fetch 'Now Playing' Data
axios.get(`${base_url}movie/now_playing?api_key=${api_key}&language=en-US&page=1`)
.then(res => this.setState({
movies: res.data.results, // for filter/remove
isLoaded: true,
defaultData: res.data.results //this will store default data
}));
}
Second option:
you can create a separate file for data services and reuse it whenever need, situation like revert,undo
GetData.js
import axios from 'axios';
// TMDB Info/Credentials
const base_url = "https://api.themoviedb/3/";
const api_key = "39b616a19667f17d8ffcaa175fc93491";
export function data() {
return axios.get(`${base_url}movie/now_playing?api_key=${api_key}&language=en-US&page=1`)
.then(res => res.data)
}
and in App.js
import {data} from './ponents/GetData';
data().then(data=>{
this.setState({
movies: data.results,
isLoaded: true,
});
});
demonstrated this here
Here's how I would do it. First some important notions:
- Updating state or props will cause rendering.
filter
will create a new array.
That means you can have a method to calculate the filtered array on the fly:
filteredMovies = () =>
this.state.movies.filter(movie =>
this.state.selectedGenres.every(genreId =>
movie.genre_ids.includes(genreId)
)
);
You can use this in your render
method:
<NowPlaying movies={this.filteredMovies()} />
The method will be called at every render, which is triggered whenever state.selectedGenres
is updated.
Now the missing piece is how the state.selectedGenres
is updated, but I think you will manage that.