@@ -2229,3 +2229,141 @@ class AppWrapper extends React.Component {
22292229 ) ;
22302230 }
22312231} ;
2232+
2233+
2234+
2235+ // ASYNC IN REDUX
2236+
2237+ // 0. create action types (/redux/actionTypes.js)
2238+ export const GET_TODOS_SUCCESS = "GET_TODOS_SUCCESS" ;
2239+ export const GET_TODOS_LOADING = "GET_TODOS_LOADING" ;
2240+ export const GET_TODOS_ERROR = "GET_TODOS_ERROR" ;
2241+
2242+ // 1. create action (/redux/actions/todosActions.js)
2243+ import {
2244+ GET_TODOS_SUCCESS ,
2245+ GET_TODOS_LOADING ,
2246+ GET_TODOS_ERROR
2247+ } from '../actionTypes' ;
2248+ export function getTodos ( todos ) {
2249+ return { type : GET_TODOS_SUCCESS , payload : todos } ;
2250+ }
2251+ export function loadingTodos ( ) {
2252+ return { type : GET_TODOS_LOADING } ;
2253+ }
2254+ export function errorTodos ( error ) {
2255+ return { type : GET_TODOS_ERROR , payload : error } ;
2256+ }
2257+ export function fetchTodos ( ) {
2258+ return function ( dispatch ) {
2259+ dispatch ( loadingTodos ( ) ) ;
2260+ fetch ( 'https://jsonplaceholder.typicode.com/todos' )
2261+ . then ( ( response ) => response . json ( ) )
2262+ // .then((x) => new Promise((resolve) => setTimeout(() => resolve(x), 1000)))
2263+ . then ( ( todos ) => {
2264+ dispatch ( getTodos ( todos ) ) ;
2265+ } )
2266+ . catch ( ( error ) => {
2267+ dispatch ( errorTodos ( error . message ) ) ;
2268+ } ) ;
2269+ } ;
2270+ }
2271+
2272+ // 2. create reducer (/redux/reducers/todosReducer.js)
2273+ import {
2274+ GET_TODOS_SUCCESS ,
2275+ GET_TODOS_LOADING ,
2276+ GET_TODOS_ERROR
2277+ } from '../actionTypes' ;
2278+ const initialState = { loading : false , todos : [ ] , error : '' } ;
2279+ export default function todoReducer ( state = initialState , action ) {
2280+ switch ( action . type ) {
2281+ case GET_TODOS_LOADING :
2282+ return { ...state , loading : true } ;
2283+ case GET_TODOS_SUCCESS :
2284+ return {
2285+ ...state ,
2286+ loading : false ,
2287+ todos : action . payload ,
2288+ error : ''
2289+ } ;
2290+ case GET_TODOS_ERROR :
2291+ return { ...state , loading : false , error : action . payload } ;
2292+ default :
2293+ return state ;
2294+ }
2295+ }
2296+
2297+ // 3. Create root reducer (/redux/reducers/index.js)
2298+ import { combineReducers } from "redux" ;
2299+ import messages from "./todosReducer" ;
2300+ export default combineReducers ( {
2301+ messages : messages
2302+ } ) ;
2303+
2304+ // 4. configure store (/redux/store.js)
2305+ import { createStore , applyMiddleware , compose } from 'redux' ;
2306+ import reduxImmutableStateInvariant from 'redux-immutable-state-invariant' ;
2307+ import thunk from 'redux-thunk' ;
2308+ import rootReducer from './reducers' ;
2309+ export default function configureStore ( initialState ) {
2310+ const composeEnhancers =
2311+ window . __REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose ;
2312+ return createStore (
2313+ rootReducer ,
2314+ initialState ,
2315+ composeEnhancers ( applyMiddleware ( thunk , reduxImmutableStateInvariant ( ) ) )
2316+ ) ;
2317+ }
2318+
2319+ // 5. Instantiate store (index.js)
2320+ import React from 'react' ;
2321+ import { render } from 'react-dom' ;
2322+ import { Provider as ReduxProvider } from 'react-redux' ;
2323+ import App from './components/App' ;
2324+ import configureStore from './redux/configureStore' ;
2325+ render (
2326+ < ReduxProvider store = { configureStore ( ) } >
2327+ < App />
2328+ </ ReduxProvider > ,
2329+ document . getElementById ( 'app' )
2330+ ) ;
2331+
2332+ // 6. Connect component && Pass props via connect && Dispatch action (/AnyComponent.js)
2333+ import React , { useEffect } from 'react' ;
2334+ import { connect } from 'react-redux' ;
2335+ import { fetchTodos } from './redux/actions/todosActions' ; // path to adapt
2336+ function App ( props ) {
2337+ const { todos, error, loading } = props . todosData ;
2338+ useEffect ( ( ) => {
2339+ props . fetchTodos ( ) ;
2340+ } , [ ] ) ;
2341+ return (
2342+ < div >
2343+ < h2 > Todos from API</ h2 >
2344+ { loading ? (
2345+ < p > Loading...</ p >
2346+ ) : (
2347+ < >
2348+ < ul >
2349+ { todos . length > 0 &&
2350+ todos . map ( ( todo ) => {
2351+ return < li key = { todo . id } > { todo . title } </ li > ;
2352+ } ) }
2353+ </ ul >
2354+ { error && < p > { error } </ p > }
2355+ </ >
2356+ ) }
2357+ </ div >
2358+ ) ;
2359+ }
2360+ function mapStateToProps ( state ) {
2361+ return { todosData : state . todos } ;
2362+ }
2363+ function mapDispatchToProps ( dispatch ) {
2364+ return {
2365+ fetchTodos : ( ) => dispatch ( fetchTodos ( ) )
2366+ } ;
2367+ }
2368+ export default connect ( mapStateToProps , mapDispatchToProps ) ( App ) ;
2369+
0 commit comments