spring-boot redux-thunk增刪改查

環境搭建

spring-boot react redux增刪改查爲基礎代碼,在redux分支的基礎上,集成redux-thunk中間件,實現增刪改查

  1. 檢出代碼
git clone https://gitee.com/qinaichen/react-crud.git
cd react-crud
  1. 切換分支
git checkout redux
  1. 創建新分支
git checkout -b redux-thunk
  1. 添加redux-thunk
cd web
npm install redux-thunk --save
  1. redux-thunk添加到store
    redux中想要使用中間件,就要使用applyMiddleware
import { createStore,applyMiddleware } from 'redux'
  1. 引入redux-thunk
import thunk from 'redux-thunk'
  1. 同時使用redux-thunkredux-devtools-extension
import { createStore,applyMiddleware , compose} from 'redux'

import thunk from 'redux-thunk'
import reducer from './reducer'

const componseEnhancers = window.__REDUX_DEVTOOLS_EXTESION_COMPOSE__ || compose;
const enhancer = componseEnhancers(
    applyMiddleware(thunk)
);
const store = createStore(reducer,enhancer);

export default store;

到這裏,我們就完全搭建好了redux-thunk的使用環境,但是我們還不能立刻使用其來完成我們的功能,首先要做的就是要將reducer中的actionaction type 抽取出來

抽取actionType

  1. store目錄先創建actionTypes.js
export const CHANGE_USER_NAME  = 'change_user_name';
export const INIT_USER_LIST = 'init_user_list';
export const EDIT_USER_NAME = 'edit_user_name'
export const SET_USER_EMPTY = 'set_user_empty';
  1. 替換reducer中的內容
import { CHANGE_USER_NAME,INIT_USER_LIST,EDIT_USER_NAME,SET_USER_EMPTY} from './actionTypes'

const defaultState = {
    id:'',
    name:'',
    list:[]
}
export default (state = defaultState,action)=>{
    /**
     * 表單控件修改邏輯
     */
    if(action.type === CHANGE_USER_NAME){
        const newState = Object.create(state);
        newState.name = action.name;
        return newState;
    }
    /**
     * 初始化list
     */
    if(action.type === INIT_USER_LIST){
        const newState = Object.create(state);
        newState.list = action.list;
        return newState;
    }
    /**
     * 編輯用戶
     */
    if(action.type === EDIT_USER_NAME){
        const newState = Object.create(state);
        const {id,name} = action.user;
        newState.id = id;
        newState.name = name;
        return newState;
    }
    /**
     * 將state中的id和name設置爲空
     */
    if(action.type === SET_USER_EMPTY){
        const newState = Object.create(state);
        const {id,name} = action.user;
        newState.id = id;
        newState.name = name;
        return newState;
    }

    return state;
}
  1. 替換App.js中的內容
import React, {Component} from 'react';
import axios from 'axios'
import './App.css'

import Table from './Table'
import Form from './Form'
import store from './store'
import { CHANGE_USER_NAME,INIT_USER_LIST,EDIT_USER_NAME,SET_USER_EMPTY} from './store/actionTypes'
class App extends Component {

    constructor(props) {
        super(props);
        this.state = store.getState();
        store.subscribe(()=>{
            this.setState(store.getState());
        })
    }

    render() {
        return (
            <div className="container-fluid" style={{marginTop: '20px'}}>
                <div className="row">
                    <div className="col-xs-4 col-xs-offset-1">
                        <Table list={this.state.list} edit={this.edit} deleteItem={this.deleteItem}></Table>
                    </div>
                    <div className="col-xs-3 col-xs-offset-1">
                        <Form name={this.state.name} handleChange={this.handleChange} submit={this.handleFormSubmit}></Form>
                    </div>
                </div>

            </div>
        );
    }

    componentDidMount(){
        this.query();
    }

    edit = (item) => {
       const action = {
           type:EDIT_USER_NAME,
           user:item
       }
       store.dispatch(action)
    }

    query = () => {
        axios.get('/user').then(({data})=>{
            const action = {
                type:INIT_USER_LIST,
                list:data
            };
            store.dispatch(action);
        })
    }
    deleteItem = (item) => {
        axios.delete(`/user/${item.id}`).then(({data})=>{
            this.query();
        })
    }

    handleChange = (name) =>{
        const action = {
            type: CHANGE_USER_NAME,
            name
        };
        store.dispatch(action);
    }

    handleFormSubmit = (e) => {
       e.preventDefault();
       if(this.state.name !== ''){
            axios.post('/user',{
                id:!this.state.id?'':this.state.id,
                name:this.state.name
            }).then(({data})=>{
                const action = {
                    type:SET_USER_EMPTY,
                    user:{id:'',name:''}
                }
                store.dispatch(action);
                this.query();
            })
       }
    }
}

export default App;

創建actionCreator

  1. store目錄下創建actionCreator.js
import { CHANGE_USER_NAME,EDIT_USER_NAME,SET_USER_EMPTY ,INIT_USER_LIST} from './actionTypes'
/**
 * 更新用戶名稱
 * @param name
 * @returns {{type: string, name: *}}
 */
export const changeUsernameAction = (name) =>({
    type: CHANGE_USER_NAME,
    name
})

/**
 * 修改用戶信息
 * @param user
 * @returns {{type: string, user: *}}
 */
export const editUserAction = (user)=>({
    type:EDIT_USER_NAME,
    user
})
/**
 * 用戶信息置空
 * @returns {{type: string, user: {id: string, name: string}}}
 */
export const setUserEmptyAction = () =>({
    type: SET_USER_EMPTY,
    user:{id:'',name:''}
})
/**
 * 初始化用戶信息列表
 * @param list
 * @returns {{type: string, list: *}}
 */
export const initUserListAction = (list) =>({
    type:INIT_USER_LIST,
    list
})
  1. App.js中引入actionCreator
import React, {Component} from 'react';
import axios from 'axios'
import './App.css'

import Table from './Table'
import Form from './Form'
import store from './store'
import {editUserAction,initUserListAction,changeUsernameAction,setUserEmptyAction} from './store/actionCreator'
class App extends Component {

    constructor(props) {
        super(props);
        this.state = store.getState();
        store.subscribe(()=>{
            this.setState(store.getState());
        })
    }

    render() {
        return (
            <div className="container-fluid" style={{marginTop: '20px'}}>
                <div className="row">
                    <div className="col-xs-4 col-xs-offset-1">
                        <Table list={this.state.list} edit={this.edit} deleteItem={this.deleteItem}></Table>
                    </div>
                    <div className="col-xs-3 col-xs-offset-1">
                        <Form name={this.state.name} handleChange={this.handleChange} submit={this.handleFormSubmit}></Form>
                    </div>
                </div>

            </div>
        );
    }

    componentDidMount(){
        this.query();
    }

    edit = (item) => {
        store.dispatch(editUserAction(item))
    }

    query = () => {
        axios.get('/user').then(({data})=>{
            store.dispatch(initUserListAction(data));
        })
    }
    deleteItem = (item) => {
        axios.delete(`/user/${item.id}`).then(({data})=>{
            this.query();
        })
    }

    handleChange = (name) =>{
        store.dispatch(changeUsernameAction(name));
    }

    handleFormSubmit = (e) => {
        e.preventDefault();
        if(this.state.name !== ''){
            axios.post('/user',{
                id:!this.state.id?'':this.state.id,
                name:this.state.name
            }).then(({data})=>{
                store.dispatch(setUserEmptyAction());
                this.query();
            })
        }
    }
}

export default App;

將異步邏輯遷入actionCreator

在沒有使用redux-thunk時,在actionCreator中定義的每一個action函數,只能返回一個對象,而使用了redux-thunk中間件,就可以讓action函數返回一個函數,返回的這個函數就能執行異步操作,所以在App.js中的查詢和刪除邏輯,都可以放到actionCreator中進行操作

  1. actionCreator中定義異步操作函數
import axios from 'axios'
/**
 * 從服務器加載用戶列表
 * @returns {Function}
 */
export const getAllUser = () =>{
    return (dispatch)=>{
        axios.get('/user').then(({data})=>{
            const action = initUserListAction(data);
            dispatch(action);
        })
    }
}
/**
 * 保存用戶信息
 * @param user
 * @returns {Function}
 */
export const saveUser = (user) =>{
    return (dispatch)=>{
        axios.post('/user',user).then(({data})=>{
            dispatch(setUserEmptyAction());
            dispatch(getAllUser());
        })
    }
}
/**
 * 刪除用戶
 * @param id
 * @returns {Function}
 */
export const deleteUser = (id) =>{
    return (dispatch)=>{
        axios.delete(`/user/${id}`).then(({data})=>{
            dispatch(getAllUser());
        })
    }
}
  1. 將異步邏輯引入App.js

import React, {Component} from 'react';
import './App.css'

import Table from './Table'
import Form from './Form'
import store from './store'

import { changeUsernameAction,
    editUserAction,
    getAllUser,
    saveUser,
    deleteUser
} from './store/actionCreator'

class App extends Component {

    constructor(props) {
        super(props);
        this.state = store.getState();
        store.subscribe(()=>{
            this.setState(store.getState());
        })
    }

    render() {
        return (
            <div className="container-fluid" style={{marginTop: '20px'}}>
                <div className="row">
                    <div className="col-xs-4 col-xs-offset-1">
                        <Table list={this.state.list} edit={this.edit} deleteItem={this.deleteItem}></Table>
                    </div>
                    <div className="col-xs-3 col-xs-offset-1">
                        <Form name={this.state.name} handleChange={this.handleChange} submit={this.handleFormSubmit}></Form>
                    </div>
                </div>

            </div>
        );
    }

    componentDidMount(){
        this.query();
    }

    edit = (item) => {
       const action =editUserAction(item);
       store.dispatch(action)
    }

    query = () => {
        const action = getAllUser();
        store.dispatch(action);
    }
    deleteItem = (item) => {
        store.dispatch(deleteUser(item.id));
    }

    handleChange = (name) =>{
        const action = changeUsernameAction(name);
        store.dispatch(action);
    }

    handleFormSubmit = (e) => {
       e.preventDefault();
       if(this.state.name !== ''){
           let user = {
               id:!this.state.id?'':this.state.id,
               name:this.state.name
           };
           const action = saveUser(user);
           store.dispatch(action);
       }
    }
}

export default App;


源碼https://gitee.com/qinaichen/react-crud.git 中的redux-thunk分支

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章