用简单的JavaScript实现类似ReactJS的功能——不知道如何减少代码的冗长



作为一个练习,我想从React创建一个useEffect、useState功能。

我实现了类似的功能,但我不喜欢代码的这一部分:

function Comp() {
let store = new Store();
let [a, setA] = useState(10, store);
let [b, setB] = useState(15, store);

基本上,每次我创建一个新的";部件";我需要创建一个商店。全局存储不起作用,因为设置新状态值时需要发送额外数据(setValue(值,"KEY"((。

有没有一种设计模式或我可以用来实现React的功能?我唯一想到的是写一个类似于transpiler的东西,但这似乎有些过头了,我好像错过了什么。

链接到沙箱:

https://codesandbox.io/s/sweet-artem-wi2imw?file=/src/store.js

编辑:

问题是如何避免将存储传递给每个新创建的组件。

编辑2:

我想要实现的功能:

  1. 我创建了一个";部件">
  2. 使用useState钩子获取[getter,setter]=useState(值(
  3. 每次调用setter时,useEffect应该调用该组件内部,或者更准确地说,应该与商店核实是否应该调用它
  4. 会有很多组件,不应从组件A调用setValue(value(在组件B中触发回调效果(为什么全局存储没有工作,除非我在setter上提供额外的参数,让存储知道应该运行哪些回调

如果你确定自己不写transpiler,请尝试decorator模式,但它只会节省你在new Store上的时间,你仍然需要手动发送它:

// something like this:
@withNewStore
function Comp(store) {
let [a, setA] = useState(10, store);
let [b, setB] = useState(15, store);

然而,如果你确定你只需要useStateuseEffect,你可以做得更狂野:

// something like this:
@withHooks
function Comp({useState,useEffect)) {
let [a, setA] = useState(10);
let [b, setB] = useState(15);

但请记住,decorator规范仍处于第2阶段,将来可能会更改。不建议在生产中使用它。

更多关于这个装饰器在typescript

根据@bbbbbbbb燕麦建议,我选择了以下解决方案

function decorate(fn) {
let store = new Store();
let props = {
useEffect: useEffectBuilder(store),
useState: useStateBuilder(store)
};
return fn(props);
}
function App() {
decorate(Comp);
decorate(Comp2);
}
function useStateBuilder(store) {
return (value) => {
return useState(value, store);
};
}
function useEffectBuilder(store) {
return (f, deps) => {
return useEffect(store, f, deps);
};
}

用法:

function Comp({useState,useEffect)) {
let [a, setA] = useState(10);
let [b, setB] = useState(15);

最新更新