Vanilla JS中的代码将实现什么,使我们能够像React中useState那样声明和更新状态:
new_tab
这个问题在JS上确实变得更好。天真地选择它是有意义的:
const [x, setX] = useState(12);
setX(14);
console.log(x); // 14
但是我不明白数组[x,setX]如何具有一个回调(setX),该回调在用const声明时会影响x?我希望这是有道理的。
答案 0 :(得分:2)
您缺少一些非常重要的东西-所有react钩子都使用“支持”它们,这使您可以在没有实例而只有函数的情况下提供有效的实例变量。
React中的这个东西叫做光纤,它有效地代表了React组件的生命周期-它本身并不与函数本身相关,它与组件相关联,而React正在渲染(和重新渲染)。这就是为什么您可以拥有一个功能组件声明,多次渲染同一功能,并且每个功能组件都能够维护自己的状态的原因-状态不是功能的一部分,状态是React光纤的一部分。
但是我不明白数组[x,setX]如何具有回调(setX) 用const声明时可能会影响x?
在调用setX
时,您并不仅仅是改变x的值,而是告诉React用新的x值重新渲染组件(光纤)。
编辑:
一个极其简单的示例,其中函数本身用作状态的后备实例(React中不是这种情况)可能看起来像这样:
// this line is example only so we can access the stateSetter external to the function
let stateSetter;
const states = new Map();
const useState = (value,context) => {
const current = states.get(context.callee) || [value,v => {
const currentState = states.get(context.callee);
currentState[0] = typeof v === 'function' ? v(currentState[0]) : v
// we recall the function with the same arguments it was originally called with - "re-rendering it" of sorts...
context.callee.call(context);
}];
states.set(context.callee,current);
return current;
}
const MyFunction = function(value) {
const [state,setState] = useState(value, arguments)
stateSetter = setState;
console.log('current value of state is: ',state)
}
MyFunction(10);
MyFunction(20); // state hasn't changed
stateSetter('new state'); // state has been updated!
答案 1 :(得分:1)
我也想学习如何做到这一点。 I found how to do it here。我重构了代码以改用 arrow functions,这会使代码片段更难阅读和理解。如果是这种情况,请前往以上链接中共享的资源。
这是实现:
const useState = (defaultValue) => {
// ? We create a function useState with a default value
let value = defaultValue;
// ? We create a local variable value = defaultValue
const getValue = () => value
// ? We create a function to set the value with parameter newValue
const setValue = newValue => value = newValue // ? We change the value for newValue
return [getValue, setValue]; // ? We return an array with the value and the function
}
const [counter, setCounter] = useState(0);
// ? We destructure the array as a return of the useState function into two value
console.log(counter()); // ? returns 0 which it's the value of counter()
为了更容易理解,我添加了注释。这是没有注释的实现:
const useState = (defaultValue) => {
let value = defaultValue;
const getValue = () => value
const setValue = newValue => value = newValue
return [getValue, setValue];
}
const [counter, setCounter] = useState(0);
console.log(counter());
为了更好地阅读和理解,我使用 regular functions 包含了该代码段:
function useState(defaultValue) {
let value = defaultValue
function getValue() {
return value
}
function setValue(newValue) {
value = newValue
}
return [getValue, setValue];
}
const [counter, setCounter] = useState(0);
答案 2 :(得分:0)
使用构造函数模拟 useState()
的简单解决方案。这可能不是最好的解决方案,因为构造函数每次都返回函数的副本,但却解决了相关问题。
function Hook(){
return function (initialState){
this.state = initialState;
return [
this.state,
function(newState){
this.state = newState;
}
];
}
}
const useState = new Hook();
现在,解构 useState()
,它是 Hook()
const [state, setState] = useState(0);
console.log(state); // 0
setState({x:20});
console.log(state); // { x: 20 }
setState({x:30});
console.log(state); // { x: 30 }