A redux egy adatokat tároló objektum, amibe helyezhetünk adatokat és olvashatjuk ki őket bármelyik másik komponensben is. Reduxban célszerű tárolni a profil adatokat beállításokat, olyan adatokat amik ritkán változnak, de sokszor van rájuk szükség, így nem kell folyamatosan újra lekérdezni őket.
Tegyük fel a react-redux csomagot az npm-el.
A chrome böngészőben levő redux-os devtool-os plugin-t használhatjuk ha szükséges, hogy megtudd nézni a böngészőben a store/state aktuális tartalmát. Ez a fejlesztésnél nagy segítség lehet. https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd
A redux használatához szükséges fájlokat négy részre osztjuk. Actions, action-types, reducers, services.
Az action-type-ban definiáljuk a redux-ban használható hívások azonosítóit. Példa action-type-ra:
// CITY
export const GET_CITY = 'GET_CITY'
export const GET_CITY_SUCCESS = 'GET_CITY_SUCCESS'
export const GET_CITY_FAILED = 'GET_CITY_FAILED'
export const GET_CITY_LIST = 'GET_CITY_LIST'
export const GET_CITY_LIST_SUCCESS = 'GET_CITY_LIST_SUCCESS'
export const GET_CITY_LIST_FAILED = 'GET_CITY_LIST_FAILED'
export const CREATE_CITY = 'CREATE_CITY'
export const EDIT_CITY = 'EDIT_CITY'
export const DELETE_CITY = 'DELETE_CITY'
export const DELETE_CITY = 'DELETE_CITY'export const DELETE_CITY = 'DELETE_CITY'export const DELETE_CITY = 'DELETE_CITY'export const DELETE_CITY = 'DELETE_CITY'export const DELETE_CITY = 'DELETE_CITY'export const DELETE_CITY = 'DELETE_CITY'export const DELETE_CITY = 'DELETE_CITY'export const DELETE_CITY = 'DELETE_CITY'
Az action-ökben deklaráljuk azokat a függvényeket, amiket meghívunk majd a komponensekből. A service-eket hívjuk meg bennük és átadjuk a redux-nak a service fügvények értékeit. Egy példa actions-re:
import * as CityService from '../services/city'
import * as actionTypes from 'modules/his/actions/action-types'
export const getCityList = (params) => {
return async (dispatch) => {
try {
dispatch({
type: actionTypes.GET_CITY_LIST,
})
let citylist = await CityService.getCityList(params)
dispatch({
type: actionTypes.GET_CITY_LIST_SUCCESS,
payload: citylist,
})
return citylist
} catch (error) {
console.log(error)
dispatch({
type: actionTypes.GET_CITY_LIST_FAILED,
payload: error,
})
throw error
}
}
}
export const getCity = (id) => {
return async (dispatch) => {
try {
dispatch({ type: actionTypes.GET_CITY })
const city = await CityService.getCity(id)
dispatch({
type: actionTypes.GET_CITY_SUCCESS,
payload: city,
})
return city
} catch (error) {
dispatch({ type: actionTypes.GET_CITY_FAILED })
throw error
}
}
}
export const createCity = (cityData) => {
return async (dispatch, getState) => {
let city = await CityService.createCity(cityData)
if (city['City'].ID) {
city = { ...cityData, ID: city['City'].ID }
}
dispatch({
type: actionTypes.CREATE_CITY,
payload: city,
})
return city
}
}
export const editCity = (id, cityData) => {
return async (dispatch, getState) => {
await CityService.editCity(cityData, id)
dispatch({
type: actionTypes.EDIT_CITY,
payload: cityData,
})
return cityData
}
}
export const deleteCity = (id) => {
return async (dispatch, getState) => {
await CityService.deleteCity(id)
dispatch({
type: actionTypes.DELETE_CITY,
payload: id,
})
return id
}
}
A reducer-ben kezeljük a fent definiált action-öket az action-type-okkal. Bekerülnek a redux state-be az adatok vagy onnan olvassuk ki őket és adjuk vissza az action-öknek. Reducer példa fájl tartalma:
import {
GET_CITY_LIST,
GET_CITY,
GET_CITY_FAILED,
GET_CITY_LIST_SUCCESS,
GET_CITY_SUCCESS,
CREATE_CITY,
DELETE_CITY,
EDIT_CITY,
} from 'modules/his/actions/action-types'
const INITIAL_STATE = {
loading: false,
error: null,
data: { data: [], count: 0 },
}
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case GET_CITY_LIST:
return {
...state,
loading: true,
}
case GET_CITY:
return {
...state,
loading: true,
}
case GET_CITY_SUCCESS:
return {
...state,
loading: false,
city: action.payload || {},
}
case GET_CITY_LIST_SUCCESS:
return {
...state,
loading: false,
data: { data: action.payload.data, count: action.payload.total },
}
case GET_CITY_FAILED:
return {
...state,
loading: false,
error: action.payload,
}
case CREATE_CITY:
return {
...state,
data: {
data: [...state.data.data, action.payload],
count: state.data.count++,
},
}
case EDIT_CITY:
return {
...state,
data: {
data: [...state.data.data.filter((city) => city.KOD !== action.payload.KOD), Object.assign({}, action.payload)],
count: state.data.count,
},
}
case DELETE_CITY:
return {
...state,
data: {
data: state.data.data.filter((city) => city.KOD !== action.payload),
count: state.data.count--,
},
}
default:
return state
}
}
Service példa fájl, amit az action hív meg:
import qs from 'query-string'
import request from 'libs/request'
import { Methods } from 'libs/http'
const BASE_URL = '/city'
export const getCity = async (id) => {
return await request({
method: Methods.GET,
resource: `${BASE_URL}/show/${id}`,
})
}
export const createCity = async (data) => {
return await request({
method: Methods.POST,
resource: `${BASE_URL}/store`,
data,
})
}
export const editCity = async (data, id) => {
return await request({
method: Methods.PUT,
resource: `${BASE_URL}/update/${id}`,
data,
})
}
export const deleteCity = async (id) => {
return await request({
method: Methods.DELETE,
resource: `${BASE_URL}/destroy/${id}`,
})
}
export const getCityList = async (params) => {
return await request({
method: Methods.GET,
resource: `${BASE_URL}?${qs.stringify(params, {
encode: false,
arrayFormat: 'bracket',
})}`,
})
}
Komponens-ben bekell "connect"-elnünk a használathoz:
import React, { PureComponent } from 'react';
import { connect } from 'react-redux'
import { getCityList, getCity, createCity, editCity, deleteCity } from './action/cityAction'
class CityPage extends PureComponent {
static propTypes = {
getCityList: PropTypes.func.isRequired,
getCity: PropTypes.func.isRequired,
createCity: PropTypes.func.isRequired,
editCity: PropTypes.func.isRequired,
deleteCity: PropTypes.func.isRequired,
};
...
load = async (params = this.props.params) => {
const city = await this.props.getCityList(...params);
}
}
const mapStateToProps = (state) => {
return {
city: state.city.data
}
}
const mapDispatchToProps = {
getCityList,
getCity,
createCity,
editCity,
deleteCity
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
Fejlesztéshez a redux tartalmát megtekinteni fel lehet tenni egy chrome extension-t, ami sokat segít. https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd
Olvasnivaló https://react-redux.js.org/ https://react-redux.js.org/introduction/quick-start