前言:用惯了get/post请求,突然来一个状态管理器,十分地不适应,网上的各式各样教程,说得都是千篇一律,没有自己见解,一直没想通用redux怎么做http请求。自己悟出来一点小门路,记下来,看以后实践起来是否正确。
分析store结构:wepy init出来的项目,src目录下有store文件夹,store文件夹的目录结构如下:
store可以理解为一个数据仓库,里面存放着
1.数据(state,隐形存在,在reducers里面定义默认值),
2.需要异步处理数据的方法(action),
3.处理数据的方法的方法名(type),
4.将action和type关系连接起来的桥梁(reducers)
下面解析每个文件夹对应的功能
types:定义action的名称
actions:异步请求,即数据异步处理在actions里进行
reducers:纯函数,接受action和当前state,返回新的state
这么讲还是有一点抽象 直接上例子
现在我们的组件有数据 user和count
user数据需要通过后台接口获取,分别有三个接口 addUser delUser updateUser
但count不需要,只是一个简单的计数器
先讲count数据的管理:(不需要异步请求)
types/count.js
export const INCREMENT = 'INCREMENT' // i++
export const DECREMENT = 'DECREMENT' // i--
actions/count.js
不需要异步操作,不需要action/count.js
reducers/count.js
import { handleActions } from 'redux-actions'
import { INCREMENT, DECREMENT} from '../types/count'
export default handleActions({
[INCREMENT] (state) {
return {
...state,
num: state.num + 1
}
},
[DECREMENT] (state) {
return {
...state,
num: state.num - 1
}
},
}, {
count: 0 // 数据count的默认值为0
})
count.wpy:在count.wpy组件中,通过state.count可以获取count,通过暴露在外的两个type:INCREMENT和DECREMENT可以实现数据的操作
count.wpy
<style lang="less"></style>
<template>
<view class="counter">
<button @tap="incNum"> INCREMENT </button>
<text class="count"> {{stateNum}} </text>
<button @tap="decNum"> DECREMENT </button>
</view>
</template>
<script>
import wepy from 'wepy'
import { connect } from 'wepy-redux'
import { INCREMENT, DECREMENT } from '../store/types/count'
@connect({
stateNum (state) {
return state.count.count
}
}, {
incNum: INCREMENT,
decNum: DECREMENT
})
export default class Counter extends wepy.component {
}
</script>
需要异步请求的user数据如下
types/user.js:三个接口,那么对应的type就有"ADD_USER" "DEL_USER" "UPDATE_USER"
export const ADD_USER = 'ADD_USER'
export const DEL_USER = 'DEL_USER'
export const UPDATE_USER = 'UPDATE_USER'
actions/user.js:处理异步请求
import { ADD_USER,DEL_USER,UPDATE_USER } from '../types/user'
import { createAction } from 'redux-actions'
import axios from 'axios'
export const addUser = createAction(ADD_USER, (user) => {
return new Promise((resolve, reject) => {
axios.post("addUser接口URL",{
user:user
})
.then(function (res) {
resolve(res)
})
.catch(function (err) {
reject(err)
});
})
})
export const delUser = createAction(DEL_USER, (userid) => {
return new Promise((resolve, reject) => {
axios.get("delUser接口URL",{
params:{
userid:userid
}
})
.then(function (res) {
resolve(res)
})
.catch(function (err) {
reject(err)
});
})
})
export const updateUser = createAction(UPDATE_USER, (userid,newuser) => {
return new Promise((resolve, reject) => {
axios.post("updateUser接口URL",{
userid:userid,
user:newuser
})
.then(function (res) {
resolve(res)
})
.catch(function (err) {
reject(err)
});
})
})
reducers/user.js
import { handleActions } from 'redux-actions'
import { ADD_USER,DEL_USER,UPDATE_USER } from '../types/user'
export default handleActions({
[ADD_USER] (state, action) {
return {
...state,
user: action.payload
}
},
[DEL_USER] (state, action) {
return {
...state,
user: action.payload
}
},
[UPDATE_USER] (state, action) {
return {
...state,
user: action.payload
}
}
}, {
user:{}
})
user.wpy
<style lang="less"></style>
<template>
<view class="user">
{{user.name}},{{user.age}}
<button @tap="addUser({name:'jack',age:18})"> addUser </button>
<button @tap="delUser('10002')"> delUser </button>
<button @tap="updateUser('1002',{name:'jack',age:18})"> updateUser </button>
</view>
</template>
<script>
import wepy from 'wepy'
import { connect } from 'wepy-redux'
import { ADD_USER,DEL_USER,UPDATE_USER } from '../store/actions/user'
@connect({
stateNum (state) {
return state.user.user
}
},
{
addUser,
delUser,
updateUser
})
export default class User extends wepy.component {
}
</script>
为了验证在没有接口的情况下异步请求操作是否可行,我们可以在官方new出来的demo下做如下修改
记得安装http和axios,用于处理异步请求
counter.wpy修改后
reducers/counter.js修改后
actions/counter.js修改后
一开始没有数据
点击ASYNC INCREMENT按钮发起异步请求后页面如下:
经过验证 axios没办法在小程序里面用 所以以上都是垃圾。把axios的请求换成wx.request吧