Reputation: 91
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
Upvotes: 0
Views: 2485
Reputation: 11257
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!!!
Upvotes: 4