react 10 state management tool 2 redux + react-redux +redux-saga

Table of Contents

  • React 10 state management tool 2 redux +
    • store/index.js entry file
    • actionType.js file of actions constants
    • rootReducer.js The total reducer is used to aggregate the reducers of all modules
    • rootSaga.js The total saga is used to aggregate the saga of all modules
    • store/form/formActions.js synchronously modify isShow
    • store/form/formReducer.js synchronously modify isShow
    • store / list / listActions.js Synchronous and asynchronous modification of count, arr
    • store / list / listReducer.js Synchronous and asynchronous modification of count, arr
    • store / list / listSaga.js Synchronous and asynchronous modification of count, arr (get the latest count and arr)
    • store/test/testActions.js data is modified asynchronously by add
    • store/test/testReducer.js data is modified asynchronously by add
    • index.js project entry file introduction
    • 7redux/3 uses saga/app.jsx
    • Effect

React 10 state management tool 2 redux +

  • npm install redux react-redux

  • npm i redux-saga

  • redux-saga

    • redux-saga is a Redux middleware that allows you to write asynchronous action creators in Redux.

store/index.js entry file

import {<!-- --> applyMiddleware, legacy_createStore } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from "./rootReducer";
import rootSaga from "./rootSaga";

const sagaMiddleware = createSagaMiddleware();

const store = legacy_createStore(rootReducer, applyMiddleware(sagaMiddleware));

sagaMiddleware.run(rootSaga);

export default store;

actionType.js actions constant file

// actionType.js constant unique identifier marks the uniqueness of the current action
export const FORM_ADD_COUNT = 'form_addCount'
export const FORM_SUB_COUNT = 'form_subCount'
export const LIST_CHANGE_IsSHOW = 'list_change_isShow'

export const TEST_CHANGE_ARR = 'test_change_arr'

rootReducer.js is the total reducer used to aggregate the reducers of all modules

// rootReducer.js The total reducer is used to aggregate the reducers of all modules
import {<!-- --> combineReducers } from 'redux';
import formReducer from './form/formReducer';
import listReducer from './list/listReducer';
import testReducer from './test/testReducer';

const rootReducer = combineReducers({<!-- -->
  list: listReducer,
  form: formReducer,
  test: testReducer
});

export default rootReducer;

rootSaga.js The total saga is used to aggregate the saga of all modules

// rootSaga.js The total saga is used to aggregate the saga of all modules
import {<!-- --> all } from 'redux-saga/effects';
import watchListActions from './list/listSaga';

function* rootSaga() {<!-- -->
  yield all([
    watchListActions()
  ]);
}

export default rootSaga;

store/form/formActions.js synchronously modify isShow

// formActions.js
import {<!-- --> LIST_CHANGE_IsSHOW } from "../actionType";
export const list_changeShow = () => ({<!-- -->
  type: LIST_CHANGE_IsSHOW,
});

store/form/formReducer.js synchronously modify isShow

// formReducer.js
import {<!-- --> LIST_CHANGE_IsSHOW } from "../actionType";
const initialState = {<!-- -->
  isShow: false
};

const formReducer = (state = initialState, action) => {<!-- -->
  switch (action.type) {<!-- -->
    case LIST_CHANGE_IsSHOW:
      return {<!-- --> ...state, isShow: !state.isShow };
    default:
      return state;
  }
};

export default formReducer;

store/list/listActions.js synchronous and asynchronous modification of count, arr

// listActions.js
import {<!-- --> FORM_ADD_COUNT, FORM_SUB_COUNT } from "../actionType";
export const form_addCount = () => ({<!-- -->
  type: FORM_ADD_COUNT
});

export const form_subCount = () => ({<!-- -->
  type: FORM_SUB_COUNT
});

store/list/listReducer.js synchronous and asynchronous modification of count, arr

// listReducer.js
import {<!-- --> FORM_ADD_COUNT, FORM_SUB_COUNT } from "../actionType";
const initialState = {<!-- -->
  count: 0
};

const listReducer = (state = initialState, action) => {<!-- -->
  switch (action.type) {<!-- -->
    case FORM_ADD_COUNT:
      return {<!-- --> ...state, count: state.count + 1 };
    case FORM_SUB_COUNT:
      return {<!-- --> ...state, count: state.count - 1 };
    default:
      return state;
  }
};

export default listReducer;

store / list / listSaga.js synchronously and asynchronously modify count and arr (get the latest count and arr)

// listSaga.js
import {<!-- --> delay, put, select, takeEvery } from 'redux-saga/effects';
import {<!-- --> FORM_ADD_COUNT, FORM_SUB_COUNT, TEST_CHANGE_ARR } from "../actionType";

function* form_addCountAsync() {<!-- -->
  // Asynchronous operations, such as sending network requests, etc.
  yield console.log('add count...',)
  // const currentCount = yield select((state) => state. list. count);
  // console.log('currentCount', currentCount); // Get the latest value of count, which can be used to initiate asynchronous requests or something
  yield delay(2000); // trigger TEST_CHANGE_ARR after 2s delay
  let currentArrLength = yield select((state) => state.test.arr)
  currentArrLength = currentArrLength?.length + 1
  console.log('currentArrLength', currentArrLength);
  yield put({<!-- --> type: TEST_CHANGE_ARR ,payload:'I am -' + currentArrLength}); // Modify the arr data of the test module
}

function* form_subCountAsync() {<!-- -->
  // Asynchronous operations, such as sending network requests, etc.
  yield console.log('sub count...');
}

function* watchListActions() {<!-- -->
  yield takeEvery(FORM_ADD_COUNT, form_addCountAsync);
  yield takeEvery(FORM_SUB_COUNT, form_subCountAsync);
}

export default watchListActions;

store / test / testActions.js is modified asynchronously by add

// testActions.js
import {<!-- --> TEST_CHANGE_ARR } from "../actionType";
export const test_change_arr = () => ({<!-- -->
  type: TEST_CHANGE_ARR,
});

store / test / testReducer.js is modified asynchronously by add

// testReducer.js
import {<!-- --> TEST_CHANGE_ARR } from "../actionType";
const initialState = {<!-- -->
  arr: []
};

const testReducer = (state = initialState, action) => {<!-- -->
  console.log('action',action);
  switch (action.type) {<!-- -->
    case TEST_CHANGE_ARR:
      return {<!-- --> ...state, arr: [...state.arr,action.payload] };
    default:
      return state;
  }
};

export default testReducer;

Introduction of index.js project entry file

import React from 'react';
import ReactDOM from 'react-dom/client';
import {<!-- --> Provider } from 'react-redux';
import App from "./7redux/3use saga/app";
import store from "./store/index.js";
const root = ReactDOM.createRoot(document.getElementById('root'));
root. render(
    <Provider store={<!-- -->store}>
        <App />
    </Provider>
);

7redux/3 uses saga/app.jsx

import React from 'react';
import {<!-- --> connect } from 'react-redux';
import {<!-- --> list_changeShow } from '../../store/form/formActions';
import {<!-- --> form_addCount, form_subCount } from '../../store/list/listActions';

class App extends React.Component {<!-- -->
  render() {<!-- -->
    // console.log('this.props',this.props);
    const {<!-- --> count, isShow, form_subCount, form_addCount, list_changeShow, arr } = this.props;

    return (
      <div>
        <p>Count: {<!-- -->count}</p>
        <button onClick={<!-- -->form_addCount}>addcount</button>
        <button onClick={<!-- -->form_subCount}>Decrement</button>

        <p>isShow: {<!-- -->isShow ? 'True' : 'False'}</p>
        <button onClick={<!-- -->list_changeShow}>Toggle Show</button>

        <p>arr: {<!-- -->arr}</p>
      </div>
    );
  }
}

const mapStateToProps = (state) => ({<!-- -->
  count: state.list.count,
  isShow: state.form.isShow,
  arr: state.test.arr,
});

const mapDispatchToProps = {<!-- -->
  form_addCount,
  form_subCount,
  list_changeShow
};

export default connect(mapStateToProps, mapDispatchToProps)(App);

Effect