![](https://jezgra.online/wp-content/uploads/2022/08/redux-toolkit-1400-1024x332.jpg)
Globalni ili “application state” je tema kojom se bavimo danas. U principu stvar funkcionira slično kao built-in React “useContext” hook.
Cijeli projekt se nalazi ovdje: LINK
Ako želimo jednostavno opisati state, možemo reći da se “state” sastoji od varijable i metode. Varijabla je trenutna vrijednost a metoda je funkcija koja postavlja tu trenutnu vrijednost. Ako se varijabla promjeni, komponente aplikacije se prilagođavaju novom state-u. Osim toga, imamo state inicijaciju, odnosno početne (init) vrijednosti state varijabli aplikacije.
Prije nego što nastavimo, ne bi bilo loše da bacimo oko na ovu objavu.
Pravimo projekt:
npx create-react-app moja-redux-aplikacija
Instaliramo Redux:
npm install --save redux react-redux npm install @reduxjs/toolkit
…pa brišemo sve u “src” mapi osim:
index.js App.js
Zbog jednostavnosti, dodajmo “školski” w3.css framework u “public/index.html” zaglavlje.
Komponente
Pravimo datoteku “/src/comps/header/header.js” sa sadržajem:
const Header = () => { return ( <div className="w3-bar w3-green"> <div className="w3-bar-item w3-black">Home</div> <div className="w3-bar-item">Posts</div> <div className="w3-bar-item">About</div> </div> ); } export default Header;
Pravimo datoteku “/src/comps/body/body.js” sa sadržajem:
const Body = () => { return ( <div className="w3-container"> <div className="w3-panel w3-blue"> <h3>Information!</h3> <p>Hello</p> </div> </div> ); } export default Body;
Zatim je uvozimo u App.js:
import Header from './comps/header/header.js'; import Body from './comps/body/body.js'; const App = () => { return ( <div className="App"> <Header /> <Body /> </div> ); } export default App;
![](https://jezgra.online/wp-content/uploads/2022/08/1.jpg)
Slice
Slice je dio state-a dodijeljen komponenti. Ime slice datoteke je naziv komponente i “Slice” sufiks. Što bi u našem primjeru bilo “HeaderSlice”, odnosno “/src/comps/header/headerSlice.js”.
import { createSlice } from "@reduxjs/toolkit"; const initialState = { currentHeader: 'home', }; export const headerSlice = createSlice({ name: "header", initialState, reducers: { }, }); export const { } = headerSlice.actions; export default headerSlice.reducer;
E sad, tu imamo “initialState” gdje postavljamo state varijablu “currentHeader” sa vrijednosti “home”. Ova je “default” postavka koja je dodijeljena varijabli pri pokretanju aplikacije.
Reducers, u biti, to su funkcije koje uzimaju neku state varijablu, mijenjaju ju i vračaju/postave novu vrijednost. Tako ćemo mi napraviti “setCurrentHeader” funkciju koja će nam postaviti novi “currentHeader”. Nakon toga, moramo eksportirati reducer.
import { createSlice } from "@reduxjs/toolkit"; const initialState = { selectedItem: 'home', changedTimes: 0, }; export const headerSlice = createSlice({ name: "header", initialState, reducers: { setCurrentHeader: (state, action) => { state.selectedItem = action.payload; }, countChange: (state) => { state.changedTimes += 1; }, }, }); export const { setCurrentHeader, countChange } = headerSlice.actions; export default headerSlice.reducer;
Store
Store je kontejner koji sadrži state aplikacije. Zato ćemo napraviti “src/store.js” datoteku sa sadržajem:
import { configureStore } from "@reduxjs/toolkit"; import headerReducer from "./comps/header/headerSlice.js"; export const store = configureStore({ reducer: { header: headerReducer, }, });
Povratak Header komponenti
Sada bi trebali malo poraditi Header komponenti. Ono što želimo je da kada kliknemo na menu item, da item bude označen.
import { useState } from "react"; const Header = () => { const barItems = ['Home','Posts','About']; const [activePage, setActivePage] = useState('home'); const createBarItem = (name, activeName) => { const key = name +'_'+ Date.now(); const nameLowerCase = name.toLowerCase(); const classString = (activeName == nameLowerCase) ? "w3-bar-item w3-black" : "w3-bar-item"; return ( <div onClick={() => setActivePage(nameLowerCase)} key={key} className={classString} >{name}</div> ); }; return ( <div className="w3-bar w3-green"> {barItems.map((barName) => ( createBarItem(barName, activePage) ))} </div> ); } export default Header;
Body state
U Body komponenti želimo znati koji je izabrani item u Header komponenti pa ga zatim prikazati u paragrafu. Ovdje izvlačimo “selectedItem” vrijednost koja je pohranjena u “application state”.
import { useSelector} from "react-redux"; const Body = () => { const { selectedItem, changedTimes } = useSelector((state) => state.header); return ( <div className="w3-container"> <div className="w3-panel w3-blue"> <h3>Information!</h3> <p>Selected item: {selectedItem}</p> <p>Count change: {changedTimes}</p> </div> </div> ); } export default Body;
Povezivanje Header komponente sa “application state”
Trenutno izabrani header item je pohranjen u “activePage” state varijabli. Da ne pišemo sad sve iznova, koristimo “useEffect” hook. Tako da kada se promjeni “activePage” vrijednost, pozivamo “setCurrentHeader” reducer i unosimo vrijednost koja je sada pohranjena u “application state”.
import { useState, useEffect } from "react"; import { useDispatch } from "react-redux"; import { setCurrentHeader, countChange } from "./headerSlice"; import './header.css'; const Header = () => { const barItems = ['Home','Posts','About']; const [activePage, setActivePage] = useState('home'); const createBarItem = (name, activeName) => { const key = name +'_'+ Date.now(); const nameLowerCase = name.toLowerCase(); const classString = (activeName == nameLowerCase) ? "w3-bar-item w3-finger w3-black" : "w3-finger w3-bar-item"; return ( <div onClick={() => setActivePage(nameLowerCase)} key={key} className={classString} >{name}</div> ); }; const dispatch = useDispatch(); useEffect(() => { dispatch(setCurrentHeader(activePage)); dispatch(countChange()); }, [activePage]); return ( <div className="w3-bar w3-green"> {barItems.map((barName) => ( createBarItem(barName, activePage) ))} </div> ); } export default Header;
![](https://jezgra.online/wp-content/uploads/2022/08/2.jpg)