状态管理使用样例
Posted zlzbt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了状态管理使用样例相关的知识,希望对你有一定的参考价值。
什么是状态管理
在react中,我们可以用过props完成一些特定场景下的状态共享,比如父子组件。但是当遇到一些其他场景时,状态共享显得特别繁琐,比如常见的跨级组件,同级组件等。虽然react提供了context API 来试图解决这方面的问题,但是还是不够优雅。现在市面上有很多优秀的状态管理库,我们一起分析看看那个更适合我们。
Redux
特点:
-
- 三大原则:单向数据流,state只读,只能通过reduce修改,reducer必须是一个纯函数。
- 由store,reducer,action三部分组成。store用于存放数据,reducer是触发action之后调用的更新方法更新store,action用于调用reducer。
- redux是js的状态管理库,在react更好的使用需要搭配react-redux。
- 不支持异步处理。需要使用三方异步中间件 。(redux-thunk,redux-saga)
- 有一定的上手成本,需要按照规范定义模版结构,也因此是大型项目状态管理的首选方案。
// main.js
import store from './store';
import Provider from 'react-redux';
ReactDOM.createRoot(document.getElementById('root') as htmlElement).render(
<Provider store=store>
<StrictMode>
<BrowserRouter>
<Layout>
<Routes />
</Layout>
</BrowserRouter>
</StrictMode>
</Provider>
);
// store.js
import applyMiddleware, legacy_createStore as createStore, compose from 'redux';
import reducer from './reducer';
import thunk from 'redux-thunk';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducer, composeEnhancers(applyMiddleware(thunk)));
export default store;
// reducer.js
import combineReducers from "redux";
import reducer as IndexReducer from '@/pages/index/store';
export default combineReducers(
Index: IndexReducer,
)
Mobx
特点:
-
- 响应式数据流,监听数据变化暴漏给所有依赖的观察者组件。
- 上手相对于redux简单,自由化相对较高。(适合中小型项目,不适合多人开发)
- 支持异步。
// store.js
import action, observable, makeObservable from 'mobx';
class Store
constructor()
makeObservable(this,
count: observable,
list: observable,
setCount: action,
setList: action
)
count = 1;
list = ;
setCount() this.count++ ;
setList(data) this.list = data ;
export const store = new Store();
// demo.js
import useObserver, useLocalStore from 'mobx-react';
import store from './store';
const Demo1 = () =>
const localStore = useLocalStore(() => store);
const addCount = () =>
localStore.setCount()
const changeList = () =>
localStore.setList( name: 'kobe' )
return useObserver(() =>
<div className='demo2'>
<button onClick=addCount>改变count</button>
<button onClick=changeList>改变List</button>
<p>count:localStore.count</p>
<p>list:localStore.list.name</p>
</div>
)
export default Demo1;
Recoil
特点:
-
- 与redux相似,在根组件用过RecoilRoot包裹,通过context传递上下文。
- 使用atom(无依赖),selector(有依赖)创建数据。
- 上手简单,没有那么多条条框框,直接简单粗暴的定义,修改即可完成使用。
import atom, selector from 'recoil';
export const countState = atom(
key: 'countState',
default: 0
)
export const dataListState = atom(
key: 'dataListState',
default:
)
export const dataState = selector(
key: 'dataState',
get: ( get ) =>
const count = get(countState);
const dataList = get(dataListState);
return
count,
dataList
)
// 消费
import useRecoilState, useSetRecoilState,useRecoilValue,useResetRecoilState from 'recoil';
const [count, setCount] = useRecoilState(countState); // 与useState类似,提供读写方法
const setDataList = useSetRecoilState(dataListState); // 仅修改
const count, dataList = useRecoilValue(dataState);// 只读
const reset = useResetRecoilState(dataState);// 重置
Zustand
特点:
-
- 通过create创建数据,在回调方法中暴漏set,get等api用于读写当前数据。
- 上手简单,写法上与Recoil类似。
- 支持异步。
// store.js
import create from "zustand";
const useStore = create((set) => (
votes: 0,
list: ,
addVotes: () => set(state => ( votes: state.votes + 1 )),
subVotes: () => set(state => ( votes: state.votes - 1 )),
getList: async () =>
const data = await mockData();
set( list: data )
))
export useStore
// demo.js
import useStore from './store';
import shallow from 'zustand/shallow';
const Demo1 = () =>
const addVotes, subVotes, getList = useStore(state => ( addVotes: state.addVotes, subVotes: state.subVotes, getList: state.getList ), shallow);
// const subVotes = useStore(state => state.subVotes);
return <div>
<button onClick=addVotes>addVotes++</button>
<button onClick=subVotes>subVotes--</button>
<button onClick=getList>getData</button>
</div>
export default Demo1;
Dva
特点:
-
- react状态管理的轻量框架,dva = react-router + redux + redux-sage + fetch。
- api简单,上手难度低。
- 支持异步,与umi搭配之后,复杂度更低。
// app.js
import dva from 'dva';
// Initialize
const app = dva();
// Model
app.model(require('./models/example').default);
// Router
app.router(require('./router').default);
// Start
app.start('#root');
// 定义modal
import mockData from '../utils/mock'
export default
namespace: 'example',
state:
list:
,
reducers:
getlist(state, data )
console.log('state====', state);
return ...state, list: data ;
,
,
effects:
*getlistAsync( payload , call, put )
const data = yield call(mockData);
yield put( type: 'getlist', data );
,
,
;
// 消费
import connect from 'dva';
import Name from './name'
function IndexPage(props)
const dispatch = props
const getlist = () =>
dispatch(
type: "example/getlistAsync",
)
;
return (
<div className=styles.normal>
<button onClick=getlist>获取列表数据</button>
<Name />
</div>
);
const mapStateToProps = (state) =>
return
example: state.example,
;
;
export default connect(mapStateToProps)(IndexPage);
// name 子组件
import connect from 'dva'
const Name = ( list ) =>
return <p>name:list.name</p>
;
const mapStateToProps = (state) =>
return
list: state.example.list
;
;
export default connect(mapStateToProps)(Name);
引用
以上是关于状态管理使用样例的主要内容,如果未能解决你的问题,请参考以下文章
Vue项目中如何快速上手Vuex状态管理--使用心得-值得珍藏