🎀个人主页:努力学习前端知识的小羊
感谢你们的支持:收藏🎄 点赞🍬 加关注🪐
Redux和React-redux
redux
redux的使用
redux
适用于多交互、多数据源的场景。
使用redux的场景:
- 某个组件的状态需要共享
- 一个组件需要改变其他组件的状态时
- 一个组件需要改变全局的状态时
redux的三大原则:
- 整个应用的
state
都被存储在一棵object tree
中,并且object tree
只存在于唯一的 store 中(这并不意味使用 redux 就需要将所有的 state 存到 redux 上,组件还是可以维护自身的 state )state
是只读的。state
的变化,会导致视图(view
)的变化。用户接触不到state
,只能接触到视图,唯一改变state
的方式则是在视图中触发action
。action
是一个用于描述已发生事件的普通对象。- 使用
reducers
来执行state
的更新。reducers
是一个纯函数,它接受action
和当前state
作为参数,通过计算返回一个新的state
,从而实现视图的更新。
Redux的工作流
- 首先,用户在视图中通过
store.dispatch
方法发出action
。 - 然后,
store
自动调用reducers
,并且传入两个参数:当前state
和收到的action
。reducers
会返回新的state
。 - 最后,当
store
监听到state
的变化,就会调用监听函数,触发视图的重新渲染
值得注意的是:Reducers不仅可以进行加工状态,还可以进行初始化状态(undefinded)
Redux API
store
- store就是保存数据的地方,整个应用只能有一个store
- redux提供createStore这个函数,用来创建一个store以存放整个应用的state
import { createStore } from "redux";
const store = createStore(reducer);
注:reducer
是一个函数,是state
操作的整合函数,每次修改state
时都会触发该函数,他的返回值会成为新的state
action
state
的变化,会导致视图的变化。但是,用户接触不到 state,只能接触到视图。所以,state 的变化必须是由视图发起的。
-action
就是视图发出的通知,通知store此时的state
应该要发生变化了。action
是一个对象。其中的type
属性是必须的,表示action
的名称
定义一个名称为change-list
的action
,他所携带的数据信息是true
const action = {
type:"change-list",
payload:true //可选属性
}
reducer
store收
到action
以后,必须给出一个新的state,视图才会进行更新。state的计算(更新)过程则是通过reducer实现reducer
是一个函数,他接受action
和当前state
作为参数,返回一个新的state
const reducer = function (state, action) {
// ...
return new_state;
};
- 为了实现调用
store.dispatch
方法自动执行reducer
函数,需要在创建store
时将reducer
传入createSore
import { createStore } from 'redux';
const reducer = function (state, action) {
// ...
return new_state;
};
const store = createStore(reducer);
上面代码中,createStore
方法接受reducer
作为参数,生成一个新的 store
。以后每当视图使用 store.dispatch
发送给 store
一个新的 action
,就会自动调用 reducer
函数,得到更新的 state
。
注: 这个 reducer 是一个纯函数。纯函数的意思是说,对于相同的输入,只会有相同的输出,不会影响外部的值,也不会被外部的值所影响。
store.dispatch()
store.dispatch
是视图发出action
的唯一方法,该方法接受一个action
对象作为参数
import { createStore } from 'redux';
const store = createStore(reducer);
store.dispatch({
type: 'ADD_TODO',
payload: 'Learn Redux' //可选属性
});
redux的方法使用
- 将reducer传递进createStore后,我们会得到一个store对象:
const store = Redux.createStore(countReducer);
- store对象创建后,对state的所有操作都需要通过它来进行:
- 读取state:
store.getState()
- 修改state:
store.dispatch({type:'ADD'})
- store还拥有一个
subscribe
方法,这个方法用来订阅state变化
的信息
store.subscribe(()=>{
// store中state发生变化时触发
console.log('state变化了')
console.log(store.getState())
});
总结:
Redux
中最最核心的东西就是这个store
,只要拿到了这个store对象就相当于拿到了Redux中存储的数据。在加上Redux的核心思想中有一条叫做“单一数据源”,也就是所有的state都会存储到一课对象树中,并且这个对象树会存储到一个store中。所以到了React中,组件只需获取到store即可获取到Redux中存储的所有state。
React-Redux
在前面我们使用redux,面对着组件无法状态无法公用,每一个状态组件都需要通过订阅来监视,状态更新会影响到全部组件更新等问题,React 官方在 redux 基础上提出了 React-Redux 库。
使用react-redux
- 安装react-redux
npm install -i react-redux
- 创建reducer
const TabbarReducer = (prevState={
show:true
},action)=>{
let newState = {...prevState}
switch (action.type) {
case "kerwinhide-tabbar":
newState.show = false
return newState;
case "kerwinshow-tabbar":
newState.show = true
return newState;
default:
return prevState
}
}
- 创建store
const store = createStore(reducer);
provider
由于我们的状态可能会被很多组件使用,所以 React-Redux 给我们提供了一个 Provider 组件,可以全局注入 redux 中的 store ,只需要把 Provider 注册在根部组件即可
ReactDOM.createRoot(document.getElementById('root')).render(
<Provider store={store}>
<App />
</Provider>
)
connect
react-redux提供connect方法,用于从UI组件生成容器组件。connect的意思,就是将这两种组件连起来
import getCinemaListAction from '../redux/actionCreator/getCinemaListAction'
import { connect } from 'react-redux'
function Cinemas(props){
// .....
}
const mapDispatchToprops = {
getCinemaListAction
}
const mapStateToProps = (state)=>{
return {
list:state.CinemaListReducer.list,
cityname:state.Cityreducer.cityname
}
}
export default connect(mapStateToProps,mapDispatchToprops)(Cinemas)
多个reducer
Redux
中是允许我们创建多个reducer的,我们可以根据它的数据和功能进行拆分,拆分后,还需要使用Redux为我们提供的函数combineReducer
将多个reducer进行合并,合并后才能传递进createStore
来创建store
。
const reducer = combineReducers({
stuReducer,
schoolReducer
});
const store = createStore(reducer);
读取数据时,直接通过state.stuReducer
和state.schoolReducer
读取数据
redux持久化
import {persistStore,persistReducer} from 'redux-persist'
import storage from 'redux-persist/lib/storage'
const persistConfig = {
key:"kerwin",
storage,
}
const reducer = combineReducers({
Cityreducer,
TabbarReducer,
CinemaListReducer
})
//改造reducer
const persistedReducer =persistReducer(persistConfig,reducer)
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(persistedReducer,composeEnhancers
(applyMiddleware(reduxThunk,reduxPromise)));
//改造store
let persistor = persistStore(store)
export {store,persistor}
改造根组件
import { Provider } from "react-redux";
import {store,persistor} from "./06-react-redux/redux/store";
import { PersistGate } from "redux-persist/integration/react";
ReactDOM.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>
,document.getElementById('root'))
总结
- Redux 是一个管理全局应用状态的库
- Redux 通常与 React-Redux 库一起使用,把 Redux 和 React 集成在一起
- Redux 使用 “单向数据流”
- State 描述了应用程序在某个时间点的状态,视图基于该 state 渲染
- 当应用程序中发生某些事情时:
- 视图 dispatch 一个 action
- store 调用 reducer,随后根据发生的事情来更新 state
- store 将 state 发生了变化的情况通知 UI
- 视图基于新 state 重新渲染
- Redux 有这几种类型的代码
- Action 是有 type 字段的纯对象,描述发生了什么
- Reducer 是纯函数,基于先前的 state 和 action 来计算新的 state
- 每当 dispatch 一个 action 后,store 就会调用 root reducer