I’ve been trying to create this search app where I can display the items in a table and delete items using react redux. However, on the initial load, the app shows a table but there is no data in the table. It’s an empty table. If i search for another movie name which have more than one movie for that search term, then 2 tables would be shown but I want to show everything on the same table itself. The delete button is not working as well. Is there something wrong with my action and reducer files?
Action.js
import { FETCH_MOVIE_PENDING, FETCH_MOVIE_SUCCESS, FETCH_MOVIE_ERROR, DELETE_MOVIE } from "./types"; const fetchMoviePendig = () => ({ type: FETCH_MOVIE_PENDING }); const fetchMovieSuccess = json => ({ type: FETCH_MOVIE_SUCCESS, payload: json }); const fetchMovieError = error => ({ type: FETCH_MOVIE_ERROR, payload: error }); export const fetchMovie = name => { return async dispatch => { dispatch(fetchMoviePendig()); try { const url = `https://jsonmock.hackerrank.com/api/movies/search/?Title=${name}`; const response = await fetch(url); const result = await response.json(response); console.log(result); dispatch(fetchMovieSuccess(result.data)); } catch (error) { dispatch(fetchMovieError(error)); } }; }; export const deleteEvent = id => async dispatch => { try { dispatch({ type: DELETE_MOVIE, payload: id }); } catch (err) { console.log(err); } };
Reducer
import { FETCH_MOVIE_PENDING, FETCH_MOVIE_SUCCESS, FETCH_MOVIE_ERROR, DELETE_MOVIE } from "../action/types"; const initialState = { data: [], loading: false, error: "" }; const moviesReducer = (state = initialState, action) => { switch (action.type) { case FETCH_MOVIE_PENDING: return { ...state, loading: true }; case FETCH_MOVIE_SUCCESS: return { ...state, loading: false, data: [...state.data, action.payload] }; case FETCH_MOVIE_ERROR: return { ...state, loading: false, error: action.payload }; case DELETE_MOVIE: return { ...state, data: state.data.filter(movie => movie.id !== action.payload) }; default: return state; } }; export default moviesReducer;
App.js
import React, { Component } from "react"; import { connect } from "react-redux"; import { fetchMovie } from "./action/movieActions"; import Input from "./components/Input"; import MovieTable from "./components/MovieTable"; class App extends Component { state = { searchInput: "The Rain" }; componentDidMount() { this.props.getMovieList(this.state.searchInput); } _getMovie = () => { this.props.getMovieList(this.state.searchInput); }; _onChangeHandler = e => { this.setState({ searchInput: e.target.value }); console.log(this.state.searchInput); }; render() { const { data, loading } = this.props.movies; return ( <div className="center"> <div> <h2 className="center white-text">Movie Search</h2> </div> <div className="container"> <Input value={this.state.searchInput} onChange={this._onChangeHandler} onClick={this._getMovie} /> <div className="row"> {loading ? ( <p>Loading</p> ) : ( data.map(item => ( <MovieTable key={item.imdbID} year={item.Year} name={item.Title} movieId={item.imdbId} /> )) )} </div> </div> </div> ); } } const mapStateToProps = state => { return { movies: state.movies }; }; const mapDispatchToProps = dispatch => { return { getMovieList: name => dispatch(fetchMovie(name)) }; }; export default connect( mapStateToProps, mapDispatchToProps )(App);
Advertisement
Answer
Hello please take a look at the sandbox : https://codesandbox.io/s/prod-wind-4hgq2?file=/src/App.js
I have edited
<MovieTable data={data.map(d => ({ year: d.Year, name: d.Title, movieId: d.imdbId }))} />
and
case FETCH_MOVIE_SUCCESS: return { ...state, loading: false, data: action.payload };
And … Currently the delete button has no event, that’s why it can’t work