0

I'm a beginner of redux. Importing api data into the console using redux-thunk and hooks into the component, but arrayed data is not available.

I'd appreciate it if you could help me figure out how to extract the data with a ui.

ActionContainer.jsx

import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchActionMovies } from '../store/actions/index';
import Movie from '../components/Movie';


const ActionContainer = (props) => {

    const dispatch = useDispatch();



    const actionData = useSelector(state => state.action);

    const [movies, setMovies] = useState(actionData);

    console.log(actionData);

    useEffect(() => {
        dispatch(fetchActionMovies());
    }, []);
    return (
        <div>
             { movies.map(movie => (
                <Movie img={movie.poster_path} key={movie.id}/>
            ))}

        </div>
    )
}

export default ActionContainer;

action/index.js

import axios from 'axios';

const API_KEY = '224ce27b38a3805ecf6f6c36eb3ba9d0';
const BASE_URL = `https://api.themoviedb.org/3`

export const FETCH_ACTION_MOVIES = 'FETCH_ACTION_MOVIES';

export const fetchActionData = (data) => {
  return {
      type: FETCH_ACTION_MOVIES,
      data
  }
}

export const fetchActionMovies = () => {
  return (dispatch) => {
    return axios.get(`${BASE_URL}/discover/movie?api_key=${API_KEY}&with_genres=28`)
      .then(response => {
        dispatch(fetchActionData(response.data))
      })
      .catch(error => {
        throw(error);
      })
  }
}

reducerAction.js

import { FETCH_ACTION_MOVIES } from '../actions/index';

export default function (state = [], action) {
  switch (action.type) {
      case FETCH_ACTION_MOVIES:
          return action.data
      default:
          return state;
  }
}

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import rootReducer from './store/reducers';
import './static/sass/style.scss';

const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(rootReducer, composeEnhancer(applyMiddleware(thunk)));

ReactDOM.render(
    <Provider store={store}><App /></Provider>,
    document.getElementById('root')
);

serviceWorker.unregister();

console.log(actionData) => (20) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

TypeError: Cannot read property 'map' of undefined

1 Answer 1

4

actionContainer.js

import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch, useStore } from 'react-redux';
import { fetchActionMovies } from '../actions/index'; // change path of action
import Movie from '../components/Movie';

const ActionContainer = (props) => {
    const dispatch = useDispatch();
    const actionData = useSelector(state => state.app.movies, []) || []; // you could use memoization to improve performance.

    useEffect(() => {
        dispatch(fetchActionMovies());
    }, []);
    return (
        <div>
            { actionData.results && actionData.results.map(movie => (
                <Movie img={movie.poster_path} />
            ))}
        </div>
    )
}

reducer/index.js

import { FETCH_ACTION_MOVIES } from '../actions/index';

export default function (state = [], action) {
  switch (action.type) {
      case FETCH_ACTION_MOVIES: // you should not mutate state
          return {
            ...state,
            movies: action.data,
        };
      default:
          return state;
  }
}

Hope that helps!!!

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your answer. But it's not working. If I look up actionData[0] on the console, TypeError: Cannot read property '0' of undefined error appears
Thank you for your helpful answers. Thanks to you, it's been solved and I've learned a lot!!
@tarzenchugh Hi, are you sure this useSelector usage for memoization? It doesn't work. When I press a button in a page ( Calling data with useSelector in the same page), useSelector works unnecessarily. What is the best usage of useSelector for memoization?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.