Redux 是一个使用叫做 “action
” 的事件来管理和更新应用状态的模式和工具库 它以集中式 Store(centralized store)
的方式对整个应用中使用的状态进行集中管理,其规则确保状态只能以可预测的方式更新。
Redux 是 JavaScript 应用的状态容器,提供可预测的状态管理。
它可以用在 react, angular, vue 等项目中。
安装
# NPM
npm install redux
# Yarn
yarn add redux
基础示例
import { createStore } from 'redux'
/**
* 这是一个 reducer 函数:接受当前 state 值和描述“发生了什么”的 action 对象,它返回一个新的 state 值。
* reducer 函数签名是 : (state, action) => newState
*
* Redux state 应该只包含普通的 JS 对象、数组和原语。
* 根状态值通常是一个对象。 重要的是,不应该改变 state 对象,而是在 state 发生变化时返回一个新对象。
*
* 你可以在 reducer 中使用任何条件逻辑。 在这个例子中,我们使用了 switch 语句,但这不是必需的。
*
*/
function counterReducer(state = { value: 0 }, action) {
switch (action.type) {
case 'counter/incremented':
return { value: state.value + 1 }
case 'counter/decremented':
return { value: state.value - 1 }
default:
return state
}
}
// 创建一个包含应用程序 state 的 Redux store。
// 它的 API 有 { subscribe, dispatch, getState }.
let store = createStore(counterReducer)
// 你可以使用 subscribe() 来更新 UI 以响应 state 的更改。
// 通常你会使用视图绑定库(例如 React Redux)而不是直接使用 subscribe()。
// 可能还有其他用例对 subscribe 也有帮助。
store.subscribe(() => console.log(store.getState()))
// 改变内部状态的唯一方法是 dispatch 一个 action。
// 这些 action 可以被序列化、记录或存储,然后再重放。
store.dispatch({ type: 'counter/incremented' })
// {value: 1}
store.dispatch({ type: 'counter/incremented' })
// {value: 2}
store.dispatch({ type: 'counter/decremented' })
// {value: 1}
- 首先,需要下载第三方包
redux
,导入项目中 - 创建
store
仓库,createStore
接收一个参数,这个参数是一个函数,这个函数被官方称做reducer
函数。 - 这个
reducer
函数接收两个参数,state
和action
,代表当前的状态和action对象。这个函数决定着如何更新状态,并且返回新的状态。 - 通过函数默认值的方式,给
state
初始值,初始值类型一般是对象。 - 访问数据,
store.getState()
API
核心概念总结
Store
在 redux 里面,只有一个Store
,整个应用需要管理的数据都在这个Store
里面。这个Store
我们不能直接去改变,我们只能通过返回一个新的Store
去更改它。redux提供了一个createStore
来创建Store;
import { createStore } from 'redux'
const store = createStore(reducer)
Action
是一个具有type
字段的普通js对象;
这个 action
指的是视图层发起的一个操作,告诉Store
我们需要改变。每个 action
必须有一个 type
属性,这表示 action
的名称,然后还可以有一个 payload
属性,这个属性可以带一些参数,用作 Store
变更:
const action = {
type: String,
payload: Object, // 可选属性,store变更的参数
}
dispatch
接收action
对象,发起修改state
。在redux里面,store.dispatch()
是 View(视图)触发 Action
的唯一方法。
store.dispatch(action)
reducer
reducer
是createStore
里面接收的参数。
reducer
是一个纯函数,不允许有任何副作用,比如发请求、操作DOM等。
纯函数简单理解就是,固定输入、固定输出、输出结果可预测。reducer函数简单理解就是,一个事件监听器,根据action.type
,返回不同的状态。
每次store.dispatch
发送一个新的action
,redux
都会自动调用reducer
,返回新的state
。
function counterReducer(state = { value: 0 }, action) {
switch (action.type) {
case 'counter/incremented':
return { value: state.value + 1 }
case 'counter/decremented':
return { value: state.value - 1 }
default:
return state
}
}
Redux的执行过程
- 创建
Store
时,Redux
就会调用一次reducer
函数,获取到默认的state
; - 当你需要更新
state
时,就会分发Action
,store.dispatch(action)
- 这时,
Redux
内部,store
就会调用reducer
函数,传入上一次的状态state
、action
对象,返回新的state
; reducer
函数执行完毕,将最新的状态交给store
,store
将用新的状态覆盖旧的状态,从而完成状态的更新;
react-redux
react-redux
是一个第三方插件使我们在react
上更方便的来使用redux
这个数据架构,简化redux
在react
项目中的使用。
- 下载第三方包,react-redux;
# If you use npm:
npm install react-redux
# Or if you use Yarn:
yarn add react-redux
- 导入Provider组件,包裹住App组件标签。然后,设置store属性,作用是让react和redux建立联系;
import {Provider} from 'react-redux'
import store from './store/index.js'
// 使用Provider组件之后,一定要设置store属性,让redux和react建立联系
React.render(<Provider store={store}>
<APP/>
</Provider>,document.getElementById('root'))
-
使用
useSelector
,接收一个回调函数,函数内部获取到最新的state
,这个函数自动驱动视图渲染,源码内部处理过了。
因此,有了这个函数,store.subscribe
这个API就可以束之高阁了。 -
使用
useDispatch
,获取dispatch
函数,触发action
改变state
;
import {useDispatch , useSelector} from 'react-redux'
export default function Child(){
// 使用useSelector,(state)=> 返回值获取到最新的state
const count=useSelector(state=>state.count)
// 使用useDispatch,获取到dispatch函数
const dispatch=useDispatch()
return(
<div>
<h1>{count}</h1>
<button onClick={()=>dispatch({type:'add',payload:1})}>+1</button>
<button onClick={()=>dispatch({type:'des',payload:1})}>-1</button>
</div>
)
}
redux-thunk异步action
一般情况 我们把对象(Object
)形式叫做同步action
函数(function
)形式称为异步action
- 安装中间件
# If you use npm:
npm install react-thunk
# Or if you use Yarn:
yarn add redux-thunk
- 配置在
store
中
import { legacy_createStore as createStore } from 'redux'
import thunk from 'react-thunk'
const store = createStore(reducer,applyMiddleware(thunk))
store.dispatch
触发异步action
store.dispatch(addAsyncAction(data,500))
- 返回一个函数同步
action
addAsyncAction=(data,time)=>{
// 返回函数异步action
return () => {
setTimeout(() => {
store.dispatch(addAction(data))
},time)
}
}
总结:
redux-thunk
这个中间件通常用于处理在redux
的ajax
请求- 在页面上,
dispatch
一个异步的action
,在这个action
内部通常做两件事情,
第一,进行异步操作,例如发起ajax
请求。
第二,dispatch
一个同步的action
,这个action
会携带ajax
请求的数据过去。