Wyszukaj / o blogu

React + Redux: prosty przykład zastosowania

Opublikowano ndz 08 listopada 2020 w redux • 2 min read

redux-react

Poniżej przedstawię przykład (oraz kolejne kroki powstania) bardzo prostego projektu wykorzystującego stan kontrolowany przez Redux. Projekt bazuje na React (CRA).

1) Instalacja narzędzi/zależności

    npx create-react-app <nazwa_projektu>
    npm i redux react-redux

2) Struktura projektu (istotne pliki/te które są edytowane oraz które zostaną/ły dodane)

    {public}
    |
    |_ [...]
    {src}
        |
        |_ {actions}
        |    |
        |    | --- index.js
        |
        |_ {reducers}
        |    |
        |    | --- index.js
        |    | --- counter.js
        |    | --- isLogged.js
        |
        |---App.js
        |---index.js
        |
        [...]

3) >>index.js<< - tutaj należy stworzyć store oraz zaimportować reduktory - window.REDUX_DEVTOOLS_EXTENSION && window.REDUX_DEVTOOLS_EXTENSION() [wcześniej window.devToolsExtension] jest przydatne w momencie tworzenia układu stanu za pomocą Reduxa, gdy nie jest jeszcze podpięty z Reactem (umożliwia komunikację z Redux Dev Tools, więcej na ten temat tutaj: Redux DevTools Extension) - App jest wskazany jako Provider (komponent wyższego rzędu) gdzie jako props przekazywany jest store

    import React from "react";
    import ReactDOM from "react-dom";
    import "./index.css";
    import App from "./App";

    import { createStore } from "redux";
    import allReducers from './reducers'

    import {Provider} from 'react-redux'



    const store = createStore(allReducers,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())


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

4) >>{reducers}<<

  • w tym folderze w poszczególnych plikach przechowywane są reduktory - funkcje tworzące nowy stan
  • ogólnie przyjęta zasada 1 plik = 1 stan (innymi słowy każdy stan posiada własny plik)

  • isLogged.js - loggedReducer przyjmuje 2 arg. 1. stan = false oraz akcję, jeśli typ akcji będzie równy SIGN_IN wówczas stan zostanie zmieniony na True

    const loggedReducer = (state=false, action) =>{
    switch(action.type) { 
        case "SIGN_IN" :
            return !state;
        default:
            return state;
    }
    }
    export default loggedReducer
    
  • counter.js - counterReducer przyjmuje 2 arg. 1 stan = 0 oraz akcję (będącą obiektem) jeśli typ akcji jest równy INCREMENT wówczas należy stan zwiększyć o wartość zawartą w action.payload a jeśli DECREMENT - odjąć 1.

    const counterReducer = (state=0, action) =>{
    switch(action.type) { 
        case "INCREMENT" :
            return state + action.payload;
        case "DECREMENT" :
            return state - 1;
        default:
            return state;
        } 
    }
    export default
    
  • index.js - skupie w sobie reduktory (przy pomocy combineReducers) i eksportuje w postaci obiektu

    import counterReducer from './counter'
    import loggedReducer from './isLogged'
    
    import { combineReducers } from 'redux'
    
    //function with object
    const allReducers = combineReducers({
        counter: counterReducer,
        isLogged: loggedReducer 
    })
    
    export default allReducers
    

5) >>{actions}<<

  • index.js - zawiera akcje (faktyczne funkcje zwracające obiekty do których należy odwołać się w komponentach), funkcja increment przyjmuje jeden argument, którego wartość przechowywana jest w zmiennej o nazwie payload
    export const increment = (num) => {
        return {
            type: "INCREMENT",
            payload: num,
        };
    };
    
    export const decrement = () => {
        return {
            type: "DECREMENT"
        };
    };
    

6) >>App.js<<

  • aplikacja - wymaga zaimportowania akcji oraz 2 hooków useSelectors oraz useDispatch
  • useSelectors jest wykorzystywany do stworzenia funkcji zmieniającej stan przy użyciu akcji
  • useDispatch jest wykorzystywany do aktualizacji stanu
    import "./App.css";
    import { useSelector, useDispatch } from "react-redux";
    import { increment, decrement } from "./actions";
    
    function App() {
    const counter = useSelector((state) => state.counter);
    const isLogged = useSelector((state) => state.isLogged);
    const dispatch = useDispatch();
    
    return (
        <div className="App">
        <h2>Counter: {counter} </h2>
        <button onClick={()=>dispatch(increment(5))}>+</button>
        <button onClick={()=>dispatch(decrement())}>-</button>
    
        {isLogged ? <h3>Info only seen if logged</h3> : ""}
        </div>
    );
    }
    
    export default App;
    

Źródła:

Redux For Beginners | React Redux Tutorial - Dev Ed