英文:
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) => {
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
// ======= now let'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 -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论