The words written in the front:

Redux can be used with libraries such as React. The following describes how to use Redux alone.

Use a





  <button id = 'plus'>  + </button>
  <span id='count'> 0 </span>
  <button id = 'minus'> - </button>
Copy the code
I. Introduction of CDN version
    <script src='https://cdn.bootcdn.net/ajax/libs/redux/4.1.0/redux.js'></script>
Copy the code

This gives you a Redux object globally

1. Create the store
 const store = Redux.createStore(reducer)
Copy the code
3. Define the initial state
    const intitalState = {
          count: 0,}Copy the code
2. Define the reducer
    const reducer = (state = intitalState, action) = > {
      switch (action.type){
        case "increment":
          return {
            count: state.count +1
          };
          case "decrement":
            return {
              count: state.count - 1
            };
          default: 
          return state
      }
    }
Copy the code
4. Define the action
    const increment = {
      type: "increment"
    }
    const decrement = {
      type: "decrement"
    }
Copy the code
5. To trigger the action
    const plus = document.getElementById("plus")
    const minus = document.getElementById("minus")
    plus.addEventListener('click'.() = > {
      store.dispatch(increment)
    })
    minus.addEventListener('click'.() = > {
      store.dispatch(decrement)
    })
Copy the code
6. Subscribe to store and update manually when status changes
store.subscribe(() = > {
    const el = document.getElementById("count");
    el.innerHTML = store.getState().count
})
Copy the code

Summarize the core API of Redux

    //1. Create Store container
    const store = Redux.createStore(reducer)
    //2. Create a Reducer of the process status
    function reducer (state, action) {
    The return value of the function is the store object
    The reducer function receives two parameters
      // State is the state to be stored in store. (This can be specified as the second parameter to createStore, or as a function default parameter.)
      // Is the triggered action object received by the second parameter on the reducer. The state in the store can be handled depending on the type value in the action
    }
    //3. Obtain the status
    store.getState()
    //4. Subscription status
    store.subscribe(function () {
    // When the state in the store changes, the store executes the function passed in SUBSCRIBE
    // This method is usually used to get the latest state of the store to update the view
    })
    / / 5. Trigger action
    store.dispatch({type: 'xxxx'}) // Trigger the action by calling Dispatch
Copy the code





Use redux in react

First, take a look at the following figure to see how Redux really works:

Next, we will combine react-Redux to reconstruct the above case step by step.

1. Install project dependencies
  • yarn add redux react-redux
2. Code replacement

Then define the Counter component in index.js, replacing the App component. And move the code we wrote before as follows:

import { createStore } from 'redux'

const intitalState = {
  count: 0,}const reducer = (state = intitalState, actions) = > {
  switch (actions.type) {
     case "increment":
          console.log("increment")
         return {
            count: state.count +1
          };
     case "decrement":
       console.log("increment")
        return {
          count: state.count - 1
        };
     default: 
      return state
  }
}

const store = createStore(reducer);
console.log(store.getState(), "state");

const increment = { type: 'increment' };
const decrement = { type: 'decrement' };

function Counter () {
  return (
      <div>
          <button id = 'plus' onClick = {()= > store.dispatch(increment)}>
              +
           </button>
           <span id='container'>
              0
           </span>
           <button id = 'minus' onClick = {()= > store.dispatch(decrement)}>
              -
            </button>
      </div>
 )}

store.subscribe(() = > {
  console.log(store.getState())
})

ReactDOM.render(
  <React.StrictMode>{/ *<App />* /}<Counter/>
  </React.StrictMode>.document.getElementById('root'));Copy the code
3. Debug the page display effect
As shown in the code, we bind click events to the button.


Go to the browser and try clicking button. You can see the following result in the console:

Thus, we can indeed successfully change the state in the store. So, when the state changes, we should synchronize to the view. That is, when the state changes, we need to re-render the next component.

So, let’s do it this way:


function Counter () {
  return <div>
  <button id = 'plus' onClick = {()= > store.dispatch(increment)}>
      +
    </button>
    <span id='container'>} {store.getState().count}</span>
    <button id = 'minus' onClick = {()= > store.dispatch(decrement)}>
      -
    </button>
  </div>
}

store.subscribe(() = > { // When the state in store changes, we render the Counter component again
  ReactDOM.render(
    <React.StrictMode>
      <Counter/>
    </React.StrictMode>.document.getElementById('root')); }) ReactDOM.render(// Get a taste of rendering components
  <React.StrictMode>{/ *<App />* /}<Counter/>
  </React.StrictMode>.document.getElementById('root'));Copy the code
conclusion

We can see that the view is actually updated. But there were a lot of problems, we only rendered the Counter component twice, and we couldn’t get store objects in other components, etc.

In the next section, we’ll take a look at how React and Redux come together.

A combination of react-redux and redux

Pre-knowledge:

React-redux contains:

1. Provider component:

What it does: Puts the store we created in a global place where each component can access it. Usage: The Provider component wraps all the components in the project, that is, it should be placed on the outermost componentCopy the code
2. Connect:

What it does: 1. It helps us subscribe to the Store and re-renders the component when the state in the store changes. 2. Help us get the state in store and map the state in store to the component using the component props property. 3. With the Connect method, we can get the Dispatch method and call the Action with the Dispatch method. Calling the connect method with: <br/> returns a method, and we need to call the returned method and pass in the component as an argument. <br/> (because when the state of the store changes, you need to know which component to update and which component to map the state in the store to)Copy the code

🌰

    import { connect } form 'react-redux';
    export default connect()(Counter)
Copy the code

Get the state in store and map it to the props of the component: The call to the connect method takes a parameter, which is a function that takes a parameter, state 🌰, in store

const mapStateToProps = state= > {// Returns an object that is mapped to the component's Pros
    return {
        count: state.count
    }
}
 export default connect(mapStateToProps)(Counter)
Copy the code
3. The second parameter to the connect method:

Map Dispatch to props of the component, where the action can be triggered by calling props. XXX

🌰

 const mapDispatchToProps = dispatch= > {// Returns an object, which is also mapped to component pros
    return {
       increment(){
          dispatch({type: 'increment'})},decrement(){
          dispatch({type: 'decrement'})}}}export defaultThe connect (mapStateToProps, mapActionToProps) (Counter)Copy the code
4. bindActionsCreators

Notice that the Increment and Decrement methods in the code above call duspatch methods and have the same structure. So we want to simplify the code, and Redux provides a bindActionsCreators method to do this, helping us generate the functions we want 🌰


// The return value of bindActionCreators is the method you passed in.
  const mapDispatchToProps = (dispatch) = > bindActionCreators({
    increment(){
        return { type: 'increment'}},decrement(){
        return { type: 'decrement' }
    }
  }, dispatch)

Copy the code
5. The action parameter

We carry the parameters in the action call of the component, and then the function defined by action in the Store module will receive the parameters we pass by default. Then we can get the parameters we pass through action. Payload from the Reducer to make the corresponding business logic 🌰

 <button id='plus'OnClick = {() => increment(5)}> + </button> 
 // actions
 const increment = (payload) = > ({ type: INCREMENT, payload })
 //reducer
 const reducer = (state, action) = > {
     switch(action. Type) {case 'increment'
         return {
             count: state.count + action.payload } ...... }}Copy the code

That’s the basics, so let’s review and refine the code

Finally:
Code refactoring & withdrawal of store modules
 // src/store/index.js
import { createStore } from 'redux';
import reducer from './reducers/counter.reducer';
const store = createStore(reducer)
Copy the code
 // src/store/reducers/counter.reducer.js
import { INCREMENT, DECREMENT } from ".. /const/count.count";

const intitalState = {
    count: 0,}export default (state = intitalState, action) => {
    switch (actions.type) {
      case INCREMENT:
        return {
          count: state.count + action.payload
        };
        case DECREMENT:
          return {
            count: state.count - action.payload
          };
        default: 
        return state
    }
  }
  
Copy the code
    // src/index.js
    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    import { Provider } from 'react-redux';
    import { store } from './store';

    ReactDOM.render(
      <React.StrictMode>
        <Provider store={store}>
          <App />
        </Provider>
        </React.StrictMode>.document.getElementById('root'));// src/App
    import  Counter  from "./components/Counter";

    function App() {
      return (
        <div className="App">
         <Counter/>
        </div>
      );
    }

    export default App;
Copy the code
//src/store/actions/counter.actions.js
import { INCREMENT, DECREMENT } from ".. /const/count.count"

export const increment = (payload) = > ({ type: INCREMENT, payload })
export const decrement = (payload) = > ({ type: DECREMENT, payload })

// src/components/Counter
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import * as counterActions from '.. /store/actions/counter.actions'
function Counter ({count,increment, decrement}) {
    return (
        <div>
            <button id = 'plus' onClick = {()= > increment(5)}>
                +
            </button>
            <span id='container'>
                {count}
            </span>
            <button id = 'minus' onClick = {()= > decrement(5)}>
                -
            </button>
        </div>)}const mapStateToProps = (state) = > ({
    count: state.count
  });

  const mapDispatchToProps = (dispatch) = > bindActionCreators(counterActions, dispatch)

  export default connect(mapStateToProps, mapDispatchToProps)(Counter)
Copy the code
Other apis

Of course, there are other methods in Redux that help us reduce code templates, such as combineReducer (to merge reducer), etc.