今天学到了redux,现在明白尤雨溪为什么用了react以后要自己做一个vue。。。
但是还是有必要去学习的
简单的说,redux就是一个所有组件都可以访问并且能够修改的state
下面说一下使用redux管理state,完成一个点击按钮修改数据的案例(案例不难,用react做肯定比redux快,只是用来教学而已)
1.在react-app中安装redux,redux-thunk(该库是为了让store能够处理异步代码)
yarn add redux redux-thunk
2.在src目录下新建redux文件夹,用来存放redux相关文件(与app同级)
3.redux目录下新建四个文件
文件解读:
store.js:核心文件,用来创建所有组件都可以访问的变量,redux目录下其他文件都是为store服务的,代码如下:
import {createStore,applyMiddleware} from 'redux' // 引入创建store方法与添加中间件方法
import thunk from 'redux-thunk' // 引入store允许异步处理的库
import CountReducer from './count_reducer' // 引入处理返回值的方法
export default createStore(CountReducer,applyMiddleware(thunk)) // 创建并暴露store
count_reducer.js:内部暴露一个方法,用来处理store的初始值以及每次修改的逻辑,代码如下:
import {ADD,SUB} from "./constant" // 引入常量,详见constant.js
export default function (prestate,action) { //有两个传参,第一个为之前的值,第二个是一个对象
const {type,data} = action //action包含两个属性,type代表标识,data代表值(组件使用时会传)
switch (type) {
case ADD:
console.log(prestate + data)
return prestate + data
case SUB:
return prestate - data
default: // 默认为0,type在第一次使用时是redux随机生成的一串字符串,不符合以上任一一项
return 0
}
}
count_action.js:用来放方法,在这次案例中是为了的需求 ,代码如下
import {ADD} from './constant'; // 引入常量
export const addCount = (val) => ({type:ADD,data:val}) // 当需要改变数据时调用这个方法
export const addAsyncCount = (val) => {
// 当redux收到的不是上面这种对象而是一个方法是,redux会把它当作需要异步操作的代码
// 会给你的函数传参,使用后会就是和上面一样的同步修改了
return (dispatch) => {
setTimeout(() => {
dispatch(addCount(val)) // 0.5秒后
},500)
}
}
constant.js:用来存放常量,防止程序员因名字问题产生bug,属于锦上添花的文件,非必要,代码如下
export const ADD = "add"
export const SUB = "sub"
4.app.js添加store渲染代码(目前学习到的,后来应该不需要用这种方式更新视图)
import store from './redux/store'
store.subscribe(() => {
ReactDOM.render(
<App />,
document.getElementById('root')
);
})
ps:因为redux只会修改数据,不会帮你重新渲染页面,redux的store在每次修改数据后,会调用subscribe,让你自己来render一下
5.App.js内部逻辑代码
import React, {Component} from 'react';
import store from './redux/store';
import {addCount,addAsyncCount} from './redux/count_action';
class App extends Component {
render() {
return (
<div>
<h1>当前计算结果为:{store.getState()}</h1>
<button onClick={() => {
this.add(1)
}}>点击+1</button>
<button onClick={() => {
this.add(2)
}}>点击+2</button>
<button onClick={() => {
this.add(1,"odd")
}}>奇数+1</button>
<button onClick={() => {
this.asyncadd(1)
}}>异步+1</button>
</div>
);
}
add = (num,action) => {
if (action == "odd") {
if (store.getState() % 2 == 1) {
store.dispatch(addCount(num))
}
} else {
// 使用后就会把addCount返回的对象传给store进行redecer内部的方法修改
store.dispatch(addCount(num))
}
}
asyncadd = (num) => {
// 异步添加,dispatch的是一个方法,在异步走成同步后需要重新dispatch
store.dispatch(addAsyncCount(num))
}
}
export default App;