react全局状态管理_React Hooks 在全局状态管理中的实践

3200796c1b39a9ca68f2cfabb775ee61.png

殷勤昨夜三更雨,又得浮生一日凉。——《鹧鸪天》苏轼

实践之结果发布于github,地址:react-duce

不知从何时起,状态管理成了一个前端项目的标配,不论有无需要,我们都会引入诸如MobX、Redux库来管理我们应用的状态。但如果我们回头想想之前项目中的某些架构,不免感叹,为何我的项目功能间设计耦合如此之紧,为什么这部分根本不需要抽离的公共状态却抽离了,又为何组件的状态和UI耦合?

自react发布之初就使用react的同学想必能感叹react发展历程中的每一步都走得稳健,从mixin到class component到function component;从pureComponent到memo,无不是在追求更好的性能与更优的程序范式。实不相瞒,自react 16.8发布hooks,我便爱react更多几分,于此对组件之间状态的管理有了更进一步的思考,完毕,凝结出了这个库react-duce,希望与大家共同探讨hooks在项目中的实践。

为何开发这个库

前段时间,看到一个通信库,swr,基于hook的数据请求库,其设计原理很容易理解,当得到返回的请求数据时,调用状态处理函数,更新状态,进而在使用该状态的组件中得到数据更新。源码片段如下:

import useSWR from 'swr'

function Profile () {

const { data, error } = useSWR('/api/user', fetcher)

if (error) return

failed to load

if (!data) return

loading...

return

hello {data.name}!

}

hook不仅使代码可读性更高,而且可使模块间耦合降低。

部分代码片段实例如下:

import React from 'react';

import { createStore, useStore } from 'react-duce';

// 创建公共store

createStore('countStore', 0);

const HelloContent = () => {

// 使用公共store

const [ count, setCount ] = useStore('countStore');

return (

setCount(count + 1)}>{count}

)

}

const WorldContent = () => {

// 使用公共store

const [ count ] = useStore('countStore');

return (

{count}

)

}

在HelloContent组件中点击span,即可触发count更新,进而WorldContent中的count也得到更新,实现组件之间store共享。

将状态管理交由reducer

曾几何时,我们感叹flux,感叹redux使我们对于状态的管理更加清晰,使我们对数据的流向胸有成竹。

e712df114bc03b95940b3e4aac3c3655.png

使用实例如下:

import React from 'react';

import { createStore, useStore } from 'react-duce';

// 定义reducer

const reducer = (state, action) => {

// you must return a new state value when a reducer is being used.

switch (action.type) {

case 'add':

const id = state.length;

return [

...state,

{ id, text: action.payload }

];

case 'delete':

return state.filter(todo => todo.id !== action.payload)

default:

return state;

}

}

// 创建指定reducer的store

const todoStore = createStore(

'todoStore',

[

{id: 0, text: 'Sing'}

],

reducer

);

function AddTodo() {

// 返回状态及dispatch函数

const [state, dispatch] = useStore('todoStore');

const inputRef = React.useRef(null);

const onSubmit = e => {

e.preventDefault();

const todo = inputRef.current.value;

inputRef.current.value = '';

// 触发状态更新

dispatch({ type: 'add', payload: todo });

};

return (

Create

);

}

function TodoList() {

const [todos, dispatch] = useStore(todoStore);

const deleteTodo = id => dispatch({ type: 'delete', payload: id });

return (

todolist

{todos.map(todo => (

{todo.text}

deleteTodo(todo.id)} type="button">

X

))}

);

}

export { TodoList, AddTodo };

实现原理

Store基类

class Store {

name;

state;

reducer;

dispatchers;

dispatch;

subscribe(callback) {};

dispatch(action, callback) {};

}

创建store

export function createStore(name, state = {}, reducer) {

const store = new Store(name, state, reducer);

$$stores = Object.assign({}, $$stores, {[name]: store})

}

使用store

export function useStore(identifier) {

const store = getStoreItem(identifier);

// 使用useState创建状态与处理函数

const [state, set] = useState(store.state);

useEffect(() => {

// ...

}, [])

return [state, store.dispatch];

}

当状态函数执行时,状态更新并遍历该状态所有set函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值