redux
redux是一个状态管理库,他并不是react的插件,只是在react中应用的比较多
image.png
根据结构图来看,redux有以下几个模块
1.Components
组件模块,用做展示数据
2.Store
Store 就是保存数据的地方,你可以把它看成一个容器。整个应用只能有一个 Store。
Redux 提供createStore这个函数,用来生成 Store。
import {createStore} from 'redux'
//生成一个store对象
const store = createStore(fn)
上面代码中,createStore函数接受另一个函数作为参数,返回新生成的 Store 对象。
3.State
Store对象包含所有数据。如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。
当前时刻的 State,可以通过store.getState()拿到。
import { createStore } from 'redux';
const store = createStore(fn);
const state = store.getState();
4.Action
State 的变化,会导致 View 的变化。但是,用户接触不到 State,只能接触到 View。所以,State 的变化必须是 View 导致的。Action 就是 View 发出的通知,表示 State 应该要发生变化了。
const action = {
type: 'add',
data:xxx
};
action为一个对象,里面两个基本的属性,第一个type,用来区分这个指令的作用,
也是和Reducer中相对应的,data为自定义的属性,里面一般用来接受参数
如何发送action通知呢
store对象提供了一个方法 store.dispatch()
import { createStore } from 'redux';
const store = createStore(fn);
store.dispatch({
type: 'add',
data:xxx
});
我们不能直接修改state中的数据,action是唯一的修改state的方法
5.Reducer
Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。
Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State。
/**
* 包含多个reducer函数的模块
*/
import React from 'react'
export function counter(state = 0, action) {
switch (action.type) {
case 'add':
return state = action.data
case 'del':
return state = action.data
case 'change':
return state = action.data
default:
return state
}
}
上面讲到创建store的时候需要传入一个函数作为参数,reducer这个模块就是去创建store对象的时候需要传入的那个参数
前面说的action的type属性就是用来标示我们需要对state进行那些更改
reducer不直接更改state,而是生成一个新的虚拟dom树,然后去和老的虚拟dom树进行对比。
接下来看一个小例子
image.png
点击增加,就每次递增1。这个demo我们把数据放在redux中,而不是直接放在组件中
组件页面
import React from 'react'
import {Component} from 'react'
class App extends Component {
constructor(props) {
super(props);
}
add = () => {
}
render() {
return (
<div>
<div>{count}</div>
<button onClick={this.add}>增加</button>
</div>
)
}
}
export default App
接下来去写reducer
/**
* 包含多个reducer函数的模块
*/
import React from 'react'
这里我们给了state一个初始值0
export function counter(state = 0, action) {
switch (action.type) {
case 'add':
return state = action.data
default:
return state
}
}
接下来去创建store对象,在入口文件里去创建
import React from 'react'
import {render} from 'react-dom'
import App from './app'
import {createStore} from 'redux'
import {counter} from './redux/reducers' 这里引入以下reducers里的counter函数
//生成一个store对象
const store = createStore(counter) //内部会初始化调用一次reducer函数,会得到一个初始state
function renders() {
// 将store对象传给组件,以方便在组件中去使用store对象
render(<App store={store}/>, document.getElementById('root'))
}
//初始化渲染组件
renders()
// 当我们更改了state的时候,生成了新的state,所以我们需要重新渲染一次组件,
这样View才会做出相应的改变,通过store的subscribe方法去监听store中的变化,并且重新渲染组件
store.subscribe(renders)
接下来就是去组件中使用store了
class App extends Component {
constructor(props) {
super(props);
}
add = () => {
let count = this.props.store.getState()
count++
通过dispatch方法去发送action通知,让reducer做出相应的改变
this.props.store.dispatch({type:'add',data:count})
}
render() {
通过store对象的getState方法获取到state,并且把他渲染到页面上
let count = this.props.store.getState()
return (
<div>
<div>{count}</div>
<button onClick={this.add}>增加</button>
</div>
)
}
}
总结一下流程,首先需要准备reducer模块,用来修改state,并且返回新的state。其次就去创建store对象,并将reducer中的函数作为参数传进去。然后将store对象传给组件,在组件中通过getState方法获取state中的数据。并且通过dispatch方法传一个action通知,去修改state的值。store.subscribe()方法来更新dom树