mtx*_*mtx 3 javascript reactjs react-hooks
管理员请注意这个问题
这个问题不是关于如何在React中编写自定义钩子。
在这个问题中回答的React状态管理的上下文中,钩子如何在后台运行也不是问题:React Hooks-后台发生了什么?
我的问题与使反应挂钩成为可能的Javascript机制有关。
-注释结尾-
React的最新发展使我们能够创建钩子。对于React状态,在以下简单函数中:
function App () {
const [someVar, setSomeVar] = useState('someVarDefaultValue');
return (
<div
onClick={() => setSomeVar('newValue')}>{someVar}
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
挂钩useState返回带有访问器和变量的数组,我们通过App函数内部的数组分解来使用它们。
因此,在幕后,该钩子看起来像(只是一个伪代码):
function useState(defaultValue) {
let value = defaultValue;
function setValue(val) {
value = val;
}
return [value, setValue];
}
Run Code Online (Sandbox Code Playgroud)
当您在JS中尝试这种方法时,它将无法正常工作-如果您在setValue某处使用,从数组分解的值将不会更新。即使您将value用作对象,也不能使用Primitive defaultValue。
我的问题是挂钩机制在JS中如何工作?
从我在React 源代码中看到的内容来看,它使用reducer函数和对Flow进行类型检查。对于我来说,要理解全局,代码很棘手。
您必须将值存储在函数外部,以便在调用之间返回持久性结果。另外,设置该值必须在其调用的组件上重新渲染:
// useState must have a reference to the component it was called in:
let context;
function useState(defaultValue) {
// Calling useState outside of a component won't work as it needs the context:
if(!context) throw new Error("Can only be called inside render");
// Only initialize the context if it wasn't rendered yet (otherwise it would re set the value on a rerender)
if(!context.value)
context.value = defaultValue;
// Memoize the context to be accessed in setValue
let memoizedContext = context;
function setValue(val) {
memoizedContext.value = val;
// Rerender, so that calling useState will return the new value
internalRender(memoizedContext);
}
return [context.value, setValue];
}
// A very simplified React mounting logic:
function internalRender(component) {
context = component;
component.render();
context = null;
}
// A very simplified component
var component = {
render() {
const [value, update] = useState("it");
console.log(value);
setTimeout(update, 1000, "works!");
}
};
internalRender(component);
Run Code Online (Sandbox Code Playgroud)
然后,当setValue被调用时,组件useState将重新渲染,将再次被调用,并且将返回新值。
| 归档时间: |
|
| 查看次数: |
908 次 |
| 最近记录: |