The use of Redux and the use of redux in React

created at 11-15-2021 views: 2

React Redux

1 Redux

# 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}

2. 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
*/

3. Asynchronous action

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))

4. Use redux's Chrome plug-in

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)))

5. Combine reducers

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)

react-redux

# Download react-redux
npm i react-redux

1. Concept

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")
     }
}

2. Use in react project

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>&nbsp;
        <button onClick={this.increament}> + </button>&nbsp;
        <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)
Please log in to leave a comment.