# Download redux
npm i redux
1. Simple use of redux:
const redux = require("redux");
// Initialize state
const initState = {
count: 0
}
// reducer, pure function
function reducer(state = initState, action) {
switch (action.type) {
case "incremnet":
return {...state, count: state.count + 1 };
case "decremnet":
return {...state, count: state.count-1 };
case "add_number":
return {...state, count: state.count + action.data };
case "sub_number":
return {...state, count: state.count-action.data };
default:
return state
}
}
// store
const store = redux.createStore(reducer);
// Subscribe to the state changes in the store
store.subscribe(() => {
console.log("state changed", store.getState());
})
// action
const action1 = {type: "incremnet" };
const action2 = {type: "decremnet" };
const action3 = {type: "add_number", data: 5 };
const action4 = {type: "sub_number", data: 8 };
// dispatch
store.dispatch(action1);
store.dispatch(action2);
store.dispatch(action3);
store.dispatch(action4);
Output result:
# state changed {count: 1}
# state changed {count: 0}
# state changed {count: 5}
# state changed {count: -3}
redux
file structure usage¶File structure using redux
:
-store
- actions # folder, store actionCreators function
- reducers # folder to store and create reducer functions
--- index.js # merge reducer
- index.js # Integrate the store object and export
- constants.js # Store the type used by the action in redux
2.1 redux code
store/constants.js
/**
* Used to save the type constant value in the action
*/
export const INCREMENT = "increment"
export const DECREMENT = "decrement"
export const ADD_PERSON = "add_person"
store/actions/count.js
import { INCREMENT, DECREMENT } from '../constants'
export function createIncrementAction(data) {
return {
type: INCREMENT,
data
}
}
export const createDecrementAction = (data) => ({type: DECREMENT, data})
store/actions/person.js
import {ADD_PERSON} from'../constants'
// Create an action to add a person
export function createAddPerson(data) {
return {
type: ADD_PERSON,
data
}
}
store/reducers/count.js
import { INCREMENT, DECREMENT } from '../constants'
export default function countReducer(state = 0, action) {
switch (action.type) {
case INCREMENT:
return state + action.data;
case DECREMENT:
return state - action.data;
default:
return state;
}
}
store/reducers/person.js
import {ADD_PERSON} from "../constants"
const initState = [
{id: "001", name: "xiaoli", age: 18 },
{id: "002", name: "Liu Zhe", age: 25 },
]
export default function personReducer(prevState = initState, action) {
switch (action.type) {
case ADD_PERSON:
return [...prevState, action.data];
default:
return prevState;
}
}
store/index.js
import {createStore, combineReducers} from'redux'
// introduce count reducer
import countReducer from'./reducers/count.js'
// Introduce person's reducer
import personReducer from "./reducers/person.js"
// merge reducer, key: value form stored in the store
const allReducers = combineReducers({
count: countReducer,
person: personReducer
})
// Expose the store object
export default createStore(allReducers)
2.2 Use redux
Create index.js
at the same level as the store
folder
import store from "./store/index.js"
import { createIncrementAction, createDecrementAction } from "./store/actions/count.js"
store.subscribe(() => {
console.log(store.getState().count);
})
store.dispatch(createIncrementAction(2));
store.dispatch(createDecrementAction(4));
store.dispatch(createDecrementAction(3));
store.dispatch(createIncrementAction(6));
/*
2
-2
-5
1
*/
Generally, actions are synchronous, that is, they are returned in object format.
The asynchronous action is in the form of a return function.
// Asynchronous action, return function
export function createAsyncIncrement(data, delay) {
// Asynchronous action return function can have two parameters
return (dispatch, getState) => {
// mimic an asynchronous request
setTimeout(() => {
dispatch("Function to create action" (data))
}, delay)
}
}
store
needs to be configured to use asynchronous middleware redux-thunk
import {createStore, applyMiddleware, combineReducers, compose} from'redux'
// Introduce redux-thunk, asynchronous action
import thunk from'redux-thunk'
export default createStore(allReducers, applyMiddleware(thunk))
First download the browser extension Redux DevTools
, which can be downloaded from the Chrome Google Store
Configure the store object
import {compose} from'redux'
// Use compose, strengthen
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
// If asynchronous middleware is used
export default createStore(allReducers, composeEnhancers(applyMiddleware(thunk)))
import {combineReducers} from'redux'
// merge reducer, key: value form stored in the store
const allReducers = combineReducers({
count: countReducer,
person: personReducer
})
// Expose the store object
export default createStore(allReducers)
# Download react-redux
npm i react-redux
Provider
provides store
to child components.
Principle: Provider
uses context
to pass store
data.
<Provider store={store}>
<App />
</Provider>,
connect
connects the store
data provided by the parent component provider
connect
is a high-level component. Use the context
in the Provider
to obtain the data in the store
, and then return a new component with the data on the store
added to the attributes.
export default connect(mapStateToProps, mapDispatchToProps)("component name")
// mapStateToProps is a function
// mapDispatchToProps is a function
function mapStateToProps(state){
return {
xxxx: state.xxxx
}
}
function mapDispatchToProps(dispatch){
return {
xxx: () => dispatch("Create action")
}
}
src/index.js
// Introduce Provider, wrap APP components
import {Provider} from "react-redux"
// Introduce store
import store from "./redux/store.js"
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
src/App.js
import React, {Component} from'react'
import Count from'./components/Count'
export default class App extends Component {
render() {
return (
<div>
{/* Use redux through react-redux */}
<Count />
</div>
)
}
}
src/components/Count.jsx
import React, {Component} from'react'
// Introduce connect
import {connect} from "react-redux"
// Introduce a function to create an action
import {createIncrementAction, createDecrementAction, createAsyncIncrement} from "../store/actions/count"
class NewCount extends Component {
optionValue = React.createRef();
increament = () => {
this.props.jia(+this.optionValue.current.value);
}
decreament = () => {
this.props.jian(+this.optionValue.current.value);
}
render() {
return (
<div>
<h2>I am the Count component</h2>
<p>The current value of count: {this.props.count}</p>
<select name="" id="" ref={this.optionValue}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button onClick={this.increament}> + </button>
<button onClick={this.decreament}>-</button>
</div>
)
}
}
// use connect
export default connect(
(state) => ({ count: state.count }),
{
jia: createIncrementAction,
jian: createDecrementAction,
// jia(num){ dispatch(createIncrementAction(num))}
})(NewCount)