Basic use of Redux

// Create the Store container
const store = Redux.createStore(reducer)
// Create the Reducer function to process state, which will also be executed at dispatch
function reducer(state) {... }// Subscribe to the state, triggering a callback when the state changes
store.subscribe(() = >{... })/ / triggers the action
store.dispatch({type: 'xxx'})
Copy the code

Install the react – story

yarn add redux react-redux
Copy the code

When the action is triggered, the reducer handler function is called, and when the task is completed in the reducer function, the subscription callback is triggered

Why use Redux

  • The parent component can use props to pass data to the child component. The child component can’t pass data to the parent component. Modifying the parent component’s data can only pass the modified method to the child component
  • Redux is used to manage data and Store data independently from components, which solves the problem of difficult data transfer between components

Use ReUDx in your project

React-redux provides Provider components that are passed to internal components through the Provider Component Store. Internal components can access the contents of the Store

import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux'

import App from './App.jsx';
import store from './store';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>.document.getElementById('root'));Copy the code
import {connect} from 'react-redux'

function App(props) {
  return (
    <div className="App">
      count:{props.count}
    </div>
  );
}
const mapStateToProps = state= >({
  count: state.count
})
export default connect(mapStateToProps)(App);

Copy the code

The second parameter in connect gives us access to the Dispatch method (we said that the dispatch method will trigger the action and will eventually execute the Reducer function).

.const mapStateToProps = state= >({
  count: state.count
})
const mapDispatchToProps = dispatch= >({
  increment(){
    return dispatch({
      type: 'increment'})},decrement(){
    return dispatch({
      type: 'decrement'})}})export default connect(mapStateToProps, mapDispatchToProps)(App);

Copy the code

Processing reducer

import {
    createStore
} from 'redux'

const initState = {
    count: 0
}

function reducer(state = initState, action) {
    switch(action.type){
        case 'decrement':
            return {
                count: state.count - 1
            };
        case 'increment':
            return {
                count: state.count + 1
            };
         default:
            return state
    }
}

const store = createStore(reducer)

export default store
Copy the code

Using bindActionsCreators

import { bindActionCreators } from 'redux'.const mapDispatchToProps = dispatch= > bindActionCreators({
  increment() {
    return {
      type: 'increment'}},decrement() {
    return {
      type: 'decrement'
    }
  }
}, dispatch)
Copy the code

Extract the action from mapDispatchToProps into a separate file

// actions.js
export const increment = () = > ({
    type: 'increment'
})

export const decrement = () = > ({
    type: 'decrement'
})
Copy the code
import * as countActions from './store/actions'.const mapDispatchToProps = dispatch= > bindActionCreators(countActions, dispatch)
Copy the code

When multiple reducers have a large number of code in them, they can be split and managed

import {
    combineReducers
} from 'redux'
import countReducer from './count'
import showReducer from './show'

export default combineReducers({
    counter: countReducer,
    modal: showReducer
})
Copy the code
// count.js
const initState = {
    count: 0
}
export default function countReducer(state = initState, action) {
    switch(action.type){
        case 'decrement':
            return {
                count: state.count + 1
            };
        case 'increment':
            return {
                count: state.count + 1
            };
         default:
            return state
    }
}
Copy the code

Used in components

.const mapStateToProps = state= > ({
  count: state.counter.count,
  show: state.modal.show
})
const mapDispatchToProps = dispatch= > bindActionCreators(countActions, dispatch)
Copy the code

Passing parameters

export const increment = payload= > ({
    type: 'increment',
    payload
})

export const decrement = payload= > ({
    type: 'decrement',
    payload
})

Copy the code
export default function countReducer(state = initState, action) {
    switch (action.type) {
        case 'decrement':
            return {
                count: state.count - (action.payload ? action.payload : 1)};case 'increment':
            return {
                count: state.count + (action.payload ? action.payload : 1)};default:
            return state
    }
}
Copy the code
<button onClick={() = > props.decrement(5)}>-</button>
Copy the code

Redux middleware

Develop a Redux middleware

export default function logger(store) {
    return next= > {
        return action= > {
            console.log(action)
            next(action)
        }
    }
}
Copy the code

Introducing middleware

import reducer from './reducers'
import {
    applyMiddleware
} from 'redux'
import logger from './middlewares/loggger'

const store = createStore(reducer, applyMiddleware(logger))

export default store
Copy the code

Develop a middleware that supports asynchronous operations

export default function thunk(store) {
    return next= > {
        return action= > {
          // If action is a function, execute the function
          // And pass the dispatch
            if (typeof action === 'function') {
                return action(store.dispatch)
            }
            next(action)
        }
    }
}
Copy the code

In an asynchronous action, when the asynchronous task finishes executing, the dispatch method is called to trigger the other action

export const deplay_increment = payload= > dispatch= > {
    setTimeout(() = > {
        dispatch(increment(payload))
    }, 2000)}Copy the code
.const store = createStore(reducer, applyMiddleware(logger, thunk))
...
Copy the code

redux-thunk

Redux-thunk is used in the same way as the Thunk middleware implemented above

.import thunk from 'redux-thunk'.const store = createStore(reducer, applyMiddleware(logger,thunk))
Copy the code

redux-actions

In the above code, we create action, write more sample code, and even need to write the action.type as a constant extracted into a separate file for management, which increases the amount of code

These processes can be simplified by using redux-Actions

import {
    createAction
} from 'redux-actions'

export const decrement = createAction('decrement')
export const increment = createAction('increment')
Copy the code
import {
    handleActions as createReducer
} from 'redux-actions'
import {
    decrement,
    increment
} from '.. /actions'

const countReducer = createReducer({
    [increment]: (state, action) = > {
        return {
            count: state.count + (action.payload ? action.payload : 1)
        }
    },
    [decrement]: (state, action) = > {
        return {
            count: state.count - (action.payload ? action.payload : 1)
        }
    }
}, initState)
export default countReducer
Copy the code

redux-saga

Redux-saga is also used to handle asynchronous operations, which can be placed in separate files

import {
    takeEvery,
    put,
    delay
} from 'redux-saga/effects'
import {
    deplay_increment,
    increment
} from '.. /actions'
// takeEvery receives the action
// put triggers the action

/ / processing
function* handleDelayIncrement(action) {
    yield delay(2000)
    / / triggers the action
    yield put(increment(action.payload))
}

export default function* CounterSaga() {
  / / receive the action
    yield takeEvery(deplay_increment, handleDelayIncrement)
}
Copy the code

Introduction of story – saga

import {
    createStore
} from 'redux'
import {
    applyMiddleware
} from 'redux'
import createSagaMiddleWare from 'redux-saga'
import reducer from './reducers'
import CounterSaga from './sagas/couter'

const sageMiddleWare = createSagaMiddleWare()
const store = createStore(reducer, applyMiddleware(sageMiddleWare))

sageMiddleWare.run(CounterSaga)

export default store
Copy the code

Merge multiple Saga files. You can merge multiple Saga files using the all method in redux-Saga/Effects

import {
    all
} from 'redux-saga/effects'
import counterSaga from './couter'
import modalSaga from './modal'

export default function* allSaga() {
    yield all([
        counterSaga(),
        modalSaga()
    ])
}
Copy the code