P14:Redux进阶-Axios异步获取数据并和Redux结合

阐述

接下来我们学习一下如何从后台取得数据,并和Redux结合,实现想要的业务逻辑。

比如以前我们的列表数据是在Reducer里写死的,本文就使用Axios从后台获取数据。

利用php创建模拟数据

在这里插入图片描述

格式

{
  "data": {
    "list": [
      '早起跑步锻炼身体',
      '中午下班休息一小时',
      '晚上8点到10点,学习两个小时'
    ]
  }
}

test.php

<?php
header('Access-Control-Allow-Origin: *');

$json = '{
  "data": {
    "list": [
      "早起跑步锻炼身体",
      "中午下班休息一小时",
      "晚上8点到10点,学习两个小时"
    ]
  }
}';

// $arr = json_decode($json,true);

echo $json;

安装并使用Axios

因为在Redux的学习中,我们使用了新的项目和目录,所以要重新安装Axios插件(以前安装的不能再使用了)。

直接使用npm进行安装。

npm install --save axios

安装完成后,就可以在 TodoList.js 中,引入并进行使用了。

import axios from 'axios'

引入后,在组件的声明周期函数里 componentDidMount 获取远程接口数据。

componentDidMount(){
    axios.get('http://tt.cc/test.php').then((res)=>{
        console.log(res)
    })
}

做完这一步骤后,可以在浏览器中打开,预览下是否控制台(console)获取数据,如果可以获取,说明完全正常。

在这里插入图片描述

获取数据后跟Redux相结合(重点)

接下来就可以把得到的数据放到Redux的store中了,这部分和以前的知识都一样,我就尽量给出代码,少讲理论了。

先创建一个函数,打开以前写的 store/actionCreatores.js 函数,然后写一个新的函数,代码如下:

export const getListAction  = (data)=>({
    type:GET_LIST,
    data
})

这时候保存会显示找不到 GET_LIST,我们再到 actionTypes.js 文件中加入一个常量。

export const  GET_LIST = 'getList'

然后引入到 actionCreatores.js 中。

import {CHANGE_INPUT , ADD_ITEM , DELETE_ITEM , GET_LIST}  from './actionTypes'

这步完成后,回到 TodoList.js 文件,继续编写axios中的回调内容,在写之前,记得先把getListAction进行引入。

import {changeInputAction , addItemAction ,deleteItemAction,getListAction} from './store/actionCreatores'
componentDidMount(){
    axios.get('http://tt.cc/test.php').then((res)=>{    
        const data = res.data
        const action = getListAction(data)
        store.dispatch(action)
    })
}

现在数据已经通过 dispatch 传递给 store 了,接下来就需要 reducer 处理业务逻辑了。

打开 reducer.js 代码如下(详细步骤在代码中作了注释):

//----关键代码--------start --------引入GET_LIST
import {CHANGE_INPUT,ADD_ITEM,DELETE_ITEM,GET_LIST} from './actionTypes'
//----关键代码--------end 
const defaultState = {
    inputValue : 'Write Something',
    //----关键代码--------start --------删除原来的初始化代码,减少冗余
    list:[]
}
export default (state = defaultState,action)=>{
    if(action.type === CHANGE_INPUT){
        let newState = JSON.parse(JSON.stringify(state)) //深度拷贝state
        newState.inputValue = action.value
        return newState
    }
    if(action.type === ADD_ITEM ){ 
        let newState = JSON.parse(JSON.stringify(state)) 
        newState.list.push(newState.inputValue)  //push新的内容到列表中去
        newState.inputValue = ''
        return newState
    }
    if(action.type === DELETE_ITEM ){ //根据type值,编写业务逻辑
        let newState = JSON.parse(JSON.stringify(state)) 
        newState.list.splice(action.index,1)  //push新的内容到列表中去
        return newState
    }
    //----关键代码--------start --------
    if(action.type === GET_LIST ){ //根据type值,编写业务逻辑
        let newState = JSON.parse(JSON.stringify(state)) 
        newState.list = action.data.data.list //复制性的List数组进去
        return newState
    }
    //----关键代码--------end --------

    return state
}

这样就完成了一次从后台请求数据,然后和Redux结合的过程。

希望小伙伴都能练习一下,我们的程序员越来越像真实的开发了,小伙伴也要在练习中不断熟悉这种开发模式。

在这里插入图片描述

demo

在这里插入图片描述

demo01\src\index.js

import React from 'react';
import ReactDOM from 'react-dom'
import TodoList from './TodoList'

ReactDOM.render(<TodoList/>,document.getElementById('root'))

demo01\src\TodoList.js

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

//关键代码-------------start
import {changeInputAction , addItemAction ,deleteItemAction,getListAction} from './store/actionCreators'
//关键代码------------end

import TodoListUI from './TodoListUI'
import axios from 'axios'

class TodoList extends Component {

    constructor(props){
        super(props)
        this.state=store.getState();
        this.changeInputValue= this.changeInputValue.bind(this)
        this.storeChange = this.storeChange.bind(this)
        this.clickBtn = this.clickBtn.bind(this)
        store.subscribe(this.storeChange) //订阅Redux的状态
    }

    render() { 
        return ( 
            <TodoListUI 
                inputValue={this.state.inputValue}
                list={this.state.list}
                changeInputValue={this.changeInputValue}
                clickBtn={this.clickBtn}
                deleteItem={this.deleteItem}
            />
        );
    }

    componentDidMount(){
        axios.get('http://tt.cc/test.php').then((res)=>{    
            const data = res.data
            const action = getListAction(data)
            store.dispatch(action)
        })
    }

    storeChange(){
        // console.log('store changed')
        this.setState(store.getState())
    }
    //--------关键代码------start
    changeInputValue(e){
        const action = changeInputAction(e.target.value)
        store.dispatch(action)
    }
    clickBtn(){
        const action = addItemAction()
        store.dispatch(action)
    }
    deleteItem(index){
        console.log(index)
        const action = deleteItemAction(index)
        store.dispatch(action)
    }
    //--------关键代码------end
}
export default TodoList;

demo01\src\TodoListUI.js

import React from 'react';
import 'antd/dist/antd.css'
import { Input , Button , List } from 'antd'

const TodoListUi = (props)=>{
    return(
        <div style={{margin:'10px'}}>
            <div>
                <Input  
                    style={{ width:'250px', marginRight:'10px'}}
                    onChange={props.changeInputValue}
                    value={props.inputValue}
                />
                <Button 
                    type="primary"
                    onClick={props.clickBtn}
                >增加</Button>
            </div>
            <div style={{margin:'10px',width:'300px'}}>
                <List
                    bordered
                    dataSource={props.list}
                    renderItem={
                        (item,index)=>(
                            <List.Item onClick={()=>{props.deleteItem(index)}}>
                                {item}
                            </List.Item>
                        )
                    }
                />    
            </div>
        </div>
    )


}

export default TodoListUi;

demo01\src\store\index.js

import { createStore } from 'redux'  //  引入createStore方法
import reducer from './reducer'    
const store = createStore(reducer,window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()) // 创建数据存储仓库
export default store   //暴露出去

demo01\src\store\reducer.js

import {CHANGE_INPUT,ADD_ITEM,DELETE_ITEM,GET_LIST} from './actionTypes'

const defaultState = {
    inputValue : 'Write Something',
    list:[
        '工作再忙也要锻炼身体',
        '中午下班休息一小时'
    ]
}

const stateAction = (state = defaultState,action)=>{

    if(action.type === CHANGE_INPUT){
        let newState = JSON.parse(JSON.stringify(state)) //深度拷贝state
        newState.inputValue = action.value
        return newState
    }

    //state值只能传递,不能使用
    if(action.type === ADD_ITEM ){
        //根据type值,编写业务逻辑
        let newState = JSON.parse(JSON.stringify(state))
        //push新的内容到列表中去
        newState.list.push(newState.inputValue)
        newState.inputValue = ''
        return newState
    }

    //根据type值,编写业务逻辑
    if(action.type === DELETE_ITEM ){ 
        let newState = JSON.parse(JSON.stringify(state))
        //push新的内容到列表中去
        newState.list.splice(action.index,1)
        return newState
    }

    if(action.type === GET_LIST ){ //根据type值,编写业务逻辑
        let newState = JSON.parse(JSON.stringify(state)) 
        newState.list = action.data.data.list //复制性的List数组进去
        return newState
    }

    return state
}

export default stateAction;

demo01\src\store\actionTypes.js

export const  CHANGE_INPUT = 'change_input_value'
export const  ADD_ITEM = 'addItem'
export const  DELETE_ITEM = 'deleteItem'
export const  GET_LIST = 'getList'

demo01\src\store\actionCreators.js

import {CHANGE_INPUT , ADD_ITEM , DELETE_ITEM , GET_LIST}  from './actionTypes'

export const changeInputAction = (value)=>({
    type:CHANGE_INPUT,
    value
})

export const addItemAction = ()=>({
    type:ADD_ITEM
})

export const deleteItemAction = (index)=>({
    type:DELETE_ITEM,
    index
})

export const getListAction  = (data)=>({
    type:GET_LIST,
    data
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知其黑、受其白

喝个咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值