How to learn redux with react?

How to work redux with react?


Redux is the state management system in react. The state is showing all data as we are seeing in the front end. Any data come first go on the redux and create a store. Store returns the previous state and is sent to the reducer. Reducer doesn’t take any action on the previous state and creates a new state back to Store on behalf of Action. Reducer is a method, so the method has two parameters: previous state and action. Action has two parts one is which type of action: add, edit, delete. The second part of action: payload.


Reducer (previous state, action) <=> Action (action type, payload) ó Payload have object: {Data: [], loading: Boolean, error: null}


Data is always in JSON format.


(Reducer not required to async method or await).


Redux example full project: Need to start create header component for the navigation.


For the routing : npm install react-router-dom


AppRouter.js

import { Route, Routes } from "react-router-dom";

import Quotes from "./view/quotes/Quotes";

import About from "./view/about/About";

import Space from "./view/space/Space";

 

export default () => {

    return (

        <>

            <Routes>

                <Route exact path="/about" element={<About />}></Route>

                <Route exact path="/space" element={<Space />}></Route>

                <Route exact path="/quotes" element={<Quotes/>}></Route>

                {/* <Route exact path="/*" element={<PageNotFound />}></Route> */}

            </Routes>

        </>

    );

};

 

 

components > Header.js

import {Link} from 'react-router-dom'

export default () => {

    return (

        <>

            <span><Link to="about"> About </Link> | </span>

            <span><Link to="quotes"> Quotes </Link> | </span>

            <span><Link to="space"> Sapce </Link></span>

        </>

    )

}


We need to install redux: npm install redux@4.0

And also need to install “npm install react-redux” for the react and redux connectivity. Then we can create a "store" folder in src folder. First we create action type file.


Store > ActionTypes.js

 

export const GET_SPACE_REQUEST = "getSpaceRequest"

export const GET_SPACE_SUCCESS = "getSpaceSuccess"

export const GET_SPACE_ERROR = "getSpaceError"

 

export const GET_QUOTE_REQUEST = "getQuoteRequest"

export const GET_QUOTE_SUCCESS = "getQuoteSuccess"

export const GET_QUOTE_ERROR = "getQuoteError"

 

 

Then need to install thunk as middleware: npm install redux-thunk


Store > Store.js

import {createStore, applyMiddleware} from 'redux';

 

import thunk from 'redux-thunk'

 

// import rootReducer from '../store/reducers/index';  

// We can call as you wish

import rootReducer from './reducers';

 

const store = createStore(rootReducer, applyMiddleware(thunk));

 

export default store;

 

Store > reducers > index.js

import SpaceReducer from './SpaceReducer'

import QuoteReducer from './QuoteReducer';

 

import {combineReducers} from 'redux';

 

const rootReducer = combineReducers({ SpaceReducer, QuoteReducer })

 

export default rootReducer;

 

Store > reducers > QuoteReducer.js

import * as ActionTypes from '../ActionTypes';

 

let initialState = { quotes: [], loading: true, error: null }

 

export default (state = initialState, action) => {

    switch(action.type){

        case ActionTypes.GET_QUOTE_REQUEST:

        case ActionTypes.GET_QUOTE_SUCCESS:

        case ActionTypes.GET_QUOTE_ERROR:

            return {

                quotes: action.payload.quotes,

                loading: action.payload.loading,

                error: action.payload.error

            };

        default:

            return state;

    }

}

 

Also you can create another more reducer same as new reducer.


Store > reducers > SpaceReducer.js

import * as ActionTypes from "../ActionTypes";

 

let initialState = { space: [], loading: false, error: null };

 

export default (state = initialState, action) => {

    //console.log();

    switch (action.type) {

        case ActionTypes.GET_SPACE_REQUEST:

        case ActionTypes.GET_SPACE_SUCCESS:

        case ActionTypes.GET_SPACE_ERROR:

            return {

                space: action.payload.space,

                loading: action.payload.loading,

                error: action.payload.error,

            };

        default:

            return state;

    }

};

 

 

Store > GetQuotes.js

import axios from 'axios'

import * as ActionTypes from './ActionTypes'

 

export function getQuotes (){

    return function (dispatch) {

        dispatch({

            type: ActionTypes.GET_QUOTE_REQUEST,

            payload: { quotes : [], loading: true, error: null}

        })

 

        axios

            .get('https://type.fit/api/quotes')

            .then((response) => {

                console.log(response);

                dispatch({

                    type: ActionTypes.GET_QUOTE_SUCCESS,

                    payload: { quotes: response.data, loading: false, error: null }

                })

            })

            .catch((error) => {

                dispatch({

                    type: ActionTypes.GET_QUOTE_ERROR,

                    payload: { quotes: [], loading: false, error: error.message }

                })

            })

    }

}

 

Store > GetSpace.js

import axios from "axios";

import * as ActionTypes from "./ActionTypes";

 

export function getSpace() {

    return function (dispatch) {

        dispatch({

            type: ActionTypes.GET_SPACE_REQUEST,

            payload: { space: [], loading: true, error: null },

        });

 

        axios

            .get("https://api.spaceXdata.com/v3/launches?limit=100&launch_success=true&land_success=true")

            .then((response) => {

                //response

                console.log(`Response`, response.data);

                dispatch({

                    type: ActionTypes.GET_SPACE_SUCCESS,

                    payload: {

                        space: response.data,

                        loading: false,

                        error: null,

                    },

                });

            })

            .catch((error) => {

                // error

                dispatch({

                    type: ActionTypes.GET_SPACE_ERROR,

                    payload: { space: [], loading: false, error: error.message },

                });

            });

    };

}

 

 

view > about > About.js

export default () => {

    return (

        <>

            <h1>About</h1>

        </>

    )

}

 

view > quotes > Quotes.js

import { useEffect } from 'react';

import {useDispatch, useSelector} from 'react-redux'

import { getQuotes } from '../../store/GetQuotes';

 

export default () => {

    const dispatch = useDispatch();

 

    const quotes = useSelector((state) => state.QuoteReducer.quotes);

    const loading = useSelector((state) => state.QuoteReducer.loading);

    const error = useSelector((state) => state.QuoteReducer.error);

 

    // console.log(quotes);

 

    useEffect(() => {

        dispatch(getQuotes());

    }, [])

 

    return (

        <>

            <section className="quoteSection">

                <div className="container">

                    <div className="row">

            <h1>Quotes More</h1>

                {loading && <div>Loading quotes...</div>}

                {!loading && error && <div>{error}</div>}

                {!loading && quotes && quotes.map((quote) =>

                    <>

                        <div className='quoteBox'>

                            <div className='quote'>{quote.text}</div>

                            <div className='quoteAuth'>{quote.author}</div>

                        </div>

                    </>

                )}

            </div>

            </div>

            </section>

        </>

    )

}

 

view > space > Space.js

 

import { useEffect } from 'react';

import {useDispatch, useSelector} from 'react-redux'

import { getSpace } from '../../store/GetSpace';

 

export default () => {

    const dispatch = useDispatch();

 

    const space = useSelector((state) => state.SpaceReducer.space);

    const loading = useSelector((state) => state.SpaceReducer.loading);

    const error = useSelector((state) => state.SpaceReducer.error);

 

    useEffect(() => {

        dispatch(getSpace());

    }, [])

 

    return (

        <>

            <section className="spaceSection">

                <div className="container">

                    <div className="row">

            <h1>Space Data</h1>

                {loading && <div>Loading Space...</div>}

                {!loading && error && <div>{error}</div>}

                {!loading && space && space.map((spacex) =>

                    <>

                        <div className='spaceBox'>

                            <div className='quote'>{spacex.mission_name}</div>

                            <div className='quoteAuth'>Launch Years: {spacex.launch_year}</div>

                        </div>

                    </>

                )}

            </div>

            </div>

            </section>

        </>

    )

}

 

App.css

 

.quoteSection {

  background: #fcf2f2;

}

 

.quoteBox {

  border: 1px solid #ccc;

  padding: 15px;

  margin: 15px;

  background: #fff;

  width: 43%;

  display: inline-block;

}

 

.quoteBox .quoteAuth {

  font-style: italic;

  color: #777;

  font-weight: 700;

}

.spaceSection{

  background: #f2f8fc;

}

.spaceBox{

  border: 1px solid #ccc;

  padding: 15px;

  margin: 10px;

  background: #fff;

  width: 20%;

  display: inline-block;

}

 

App.js

import './App.css';

import AppRouter from './AppRouter';

import Header from './components/Header';

 

function App() {

  return (

    <>

      <Header />

     <AppRouter/>

    </>

  );

}

 

export default App;

 

 

We need to add first BrowserRouter import from react-router-dom for the routing purpose. For the store we need to wrap Provider component and call store attribute and pass store as imported store.


Index.js

import React from 'react';

import ReactDOM from 'react-dom/client';

import './index.css';

import App from './App';

import reportWebVitals from './reportWebVitals';

import {BrowserRouter} from 'react-router-dom'

 

import {Provider} from 'react-redux'

import store from './store/Store';

 

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(

  <React.StrictMode>

    <Provider store={store}>

      <BrowserRouter>

        <App />

      </BrowserRouter>

    </Provider>

  </React.StrictMode>

);

 

// If you want to start measuring performance in your app, pass a function

// to log results (for example: reportWebVitals(console.log))

// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals

reportWebVitals();

 

 

Note: I have used api in my code for the testing purpose ONLY you will use your other api.


Please check the folder structure as above example. 




No comments:

Note: Only a member of this blog may post a comment.

Copyright Reserved to Anything Learn. Powered by Blogger.