在Vanilla JavaScript/Node上复制React的useState

huangapple go评论53阅读模式
英文:

Replicating React useState on Vanilla Javascript/Node

问题

这个useState()函数返回一个初始化值并将其存储在stateValues数组中,但它实际上不引用数组位置。

现在,我可以让useState返回一个箭头函数,该函数返回stateValues[currentCallIndex],但这样我每次需要状态值时都必须调用一个函数。

是否有一种更符合React风格的方式来通过引用返回更新后的值(而不是countA()而是countA)?

英文:

I'm trying to get back the state value from this useState Vanilla JS replica:

let callIndex = -1

const stateValues = []

const useState = (initialValue) => {
    callIndex++ // 0

    const currentCallIndex = Number(callIndex) // 0

    if (stateValues[currentCallIndex] === undefined){
        stateValues[currentCallIndex] = initialValue
    }

    const setValue = (newValue) => {
        stateValues[currentCallIndex] = newValue
    }

    return [stateValues[currentCallIndex], setValue]
}

const [countA, setCountA] = useState(1)
const [countB, setCountB] = useState(-1)

This useState() function returns an initializing value and storing it in the stateValues array. But it doesn't actually refer to the array position.

setCountA(3)
// LOGs->   stateValues[0]:  3, stateValues[1]:  -1,  countA:  1,  countB:  -1
setCountA(5)
setCountB(9)
// LOGs->    stateValues[0]:  5, stateValues[1]:  9,  countA:  1,  countB:  -1
setCountA(2)
setCountB(5)
// LOGs->   stateValues[0]:  2, stateValues[1]:  5,  countA:  1,  countB:  -1

Now, I can make useState return an arrow function that returns stateValues[currentCallIndex] but then I have to call a function every time I need a state value.

Is there a more Reactsy way of returning the updated value by reference (countA rather than countA() )?

答案1

得分: 1

如果您坚持按照 React 的方式执行,而不实际实现组件生命周期逻辑,可以像这样操作:

let callIndex = -1;
const states = [];

const useState = (initialValue) => {
    const currentCallIndex = callIndex++;

    states[currentCallIndex] = states[currentCallIndex] ?? {
        value: initialValue,
        setValue: (newValue) => {
            states[currentCallIndex].value = newValue;
        },
    };

    return states[currentCallIndex];
};

let stateA = useState(1);
let stateB = useState(-1);

console.log(stateA.value, stateB.value); // 1, -1

stateA.setValue(2);
stateB.setValue(3);

console.log(stateA.value, stateB.value); // 2, 3

// ======= 现在让我们重置索引 =======
callIndex = -1;

// ======= 并检查状态是否持久 =======
stateA = useState(1);
stateB = useState(-1);

console.log(stateA.value, stateB.value); // 2, 3

参考链接

英文:

If you insist on doing it the React way without implementing an actual component lifecycle logic, you can do something like this:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let callIndex = -1

const states = []

const useState = (initialValue) =&gt; {
    const currentCallIndex = callIndex++

    states[currentCallIndex] = states[currentCallIndex] ?? {
      value: initialValue,
      setValue: (newValue) =&gt; {
        states[currentCallIndex].value = newValue;
      },
    }

    return states[currentCallIndex]
}

let stateA = useState(1)
let stateB = useState(-1)

console.log(stateA.value, stateB.value) // 1, -1

stateA.setValue(2)
stateB.setValue(3)

console.log(stateA.value, stateB.value) // 2, 3

// ======= now let&#39;s reset the index =======
callIndex = -1;

// ======= and check that the state is persistent =======
stateA = useState(1)
stateB = useState(-1)

console.log(stateA.value, stateB.value) // 2, 3

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年2月9日 01:18:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/75389439.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定