redux-thunk使用流程

首先安装redux-thunknpm install redux-thunk
其次在创建store的时候,使用thunk中间件,照着官方文档,一步一步去配置,通过enhancer 这样一个内容,把他传递给createStore的第二个参数,使得我们这样一个store仓库,既使用了thunk又使用了REDUX_DEVTOOLS开发者工具。

store文件夹下的index.js

import { createStore, applyMiddleware, compose } from 'redux';
import reducer from './reducer';
import thunk from 'redux-thunk';

// compose需要引入
const composeEnhancers =
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?   
        window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
        }) : compose;

const enhancer = composeEnhancers(
    applyMiddleware(thunk),    
);

//创建store的时候,使用reducer构建初始数据,创建store的时候,store会使用一个中间件,也就是thunk的中间件
const store = createStore(
    reducer,
    enhancer   
);

export default store;

配置好redux-thunk开发环境后,使得我们可以在action中使用异步的代码。
打开之前写得todolist之后,当组件挂载完成之后,以前创建一个action只能是一个js对象,现在当使用了redux-thunk之后,即使getTodoList返回的不是一个对象而是一个函数,也可以通过store.dispatch(action);发送给store了。

componentDidMount(){
        // axios.get('/list.json').then((res)=>{
        //     const data = res.data;
        //     const action = initListAction(data);
        //     store.dispatch(action);
        // })
        const action = getTodoList();
        store.dispatch(action);
        // console.log(action);
    }

实际上 store只能接受一个对象,store发现你这是一个函数,就会做帮你自动的执行action对应的这个函数,也就是在获取json数据的那个函数,你获取了数据之后,你就要改变store的数据,又要走redux的流程,先创建一个action

// 正常来说 return出去的是一个对象,但是使用redux之后,可以return出去一个函数,在这个函数里可以做异步的操作
// 当调用getTodoList生成内容函数的时候,这个函数能够接收store的dispatch
export const getTodoList = () => {
    return (dispatch) => {
         axios.get('/list.json').then((res)=>{
            const data = res.data;
            const action = initListAction(data);
            dispatch(action);
            // console.log(data);
            // const action = initListAction(data);
            // store.dispatch(action);
        })
    }
}

随着你代码量的提升,你对代码的理解,大家会逐步理解,把异步函数放在组件的生命周期函数里做,这个生命函数有可能会变得越来越复杂,越来越多,然后这个组件就会变得越来越大。

TodoList.js

import React,{Component} from 'react';
import 'antd/dist/antd.css';
import store from './store';
import { getInputChangeAction, getAddItemAction, getDeleteItemAction, getTodoList } from './store/actionCreators';
import TodoListUI from './TodoListUI';


class TodoList extends Component{

    constructor(props){
        super(props);
        this.state=store.getState();
        this.handleInputChange=this.handleInputChange.bind(this);
        this.handleBtnClick=this.handleBtnClick.bind(this);
        this.handleStoreChange=this.handleStoreChange.bind(this);
        this.handleItemDelete = this.handleItemDelete.bind(this);
        //store里面的数据只要发生改变,subscribe里面函数就会被自动的执=行
        store.subscribe(this.handleStoreChange);
    }

    render(){
        return (
            <TodoListUI 
                inputValue={this.state.inputValue}
                list={this.state.list}
                handleInputChange={this.handleInputChange}
                handleBtnClick={this.handleBtnClick}
                handleItemDelete= {this.handleItemDelete}
            />
        )
    }

    componentDidMount(){
        // axios.get('/list.json').then((res)=>{
        //     const data = res.data;
        //     const action = initListAction(data);
        //     store.dispatch(action);
        // })
        const action = getTodoList();
        store.dispatch(action);
        // console.log(action);
        
    }
    handleInputChange(e){
        // 去改变store里面的内容,首先要创建一句话,告诉store
        const action = getInputChangeAction(e.target.value);
        // 将这句话传递给store
        store.dispatch(action);
    }

    handleStoreChange(){
        //当感知到store的数据变化的时候,调用store.getState()方法,
        //从store里面重新取一次数据,然后调用setState替换当前组件里的数据
        // 这样组件里的数据,就和store里的数据同步了
       this.setState(store.getState());
    }

    handleBtnClick(){
        const action = getAddItemAction();
        store.dispatch(action);
    }

    handleItemDelete(index){
        const action = getDeleteItemAction(index);
        store.dispatch(action);
        // alert(index);
    }

}
export default TodoList;

TodoListUI.js

import React from 'react';
import { Input, Button, List } from 'antd';

const TodoListUI = (props)=>{
	return (
		<div style={{marginTop:'10px',marginLeft:'10px'}}>
				<div>
					<Input 
					value={props.inputValue} 
					placeholder='todo info' 
					style={{width:'300px',marginRight:'10px'}}
					onChange={props.handleInputChange}
					/>
					<Button type="primary" onClick={props.handleBtnClick}>提交</Button>
				</div>
				<List
					style={{marginTop:'10px',width:'300px'}}
					bordered
					dataSource={props.list}
					renderItem={(item,index) => (<List.Item onClick={()=>{props.handleItemDelete(index)}}>{item}</List.Item>)}
				/>
		</div>
	)
}
export default TodoListUI;

ActionCreators.js

import axios from 'axios';
import { CHANGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM, INIT_LIST_ACTION } from './actionTypes';

export const getInputChangeAction =(value)=>({
    type: CHANGE_INPUT_VALUE,
    value
});

export const getAddItemAction =()=>({
    type: ADD_TODO_ITEM
});

export const getDeleteItemAction =(index)=>({
    type: DELETE_TODO_ITEM,
    index
});

export const initListAction =(data)=>({
    type: INIT_LIST_ACTION,
    data
});
// 正常来说 return出去的是一个对象,但是使用redux之后,可以return出去一个函数,在这个函数里可以做异步的操作
// 当调用getTodoList生成内容函数的时候,这个函数能够接收store的dispatch
export const getTodoList = () => {
    return (dispatch) => {
         axios.get('/list.json').then((res)=>{
            const data = res.data;
            const action = initListAction(data);
            dispatch(action);
            // console.log(data);
            // const action = initListAction(data);
            // store.dispatch(action);
        })
    }
}

actionTypes.js

export const CHANGE_INPUT_VALUE = 'change_input_value';
export const ADD_TODO_ITEM = 'add_todo_item';
export const DELETE_TODO_ITEM = 'delete_todo_item';
export const INIT_LIST_ACTION = 'init_list_action';
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值