小编典典

react hooks后面的JavaScript机制如何工作?

reactjs

我的问题与使反应挂钩成为可能的Javascript机制有关。

React的最新发展使我们能够创建钩子。对于React状态,在以下简单函数中:

function App () {
  const [someVar, setSomeVar] = useState('someVarDefaultValue');
  return (
    <div 
      onClick={() => setSomeVar('newValue')}>{someVar}
    </div>
  );
}

挂钩useState返回带有访问器和变量的数组,我们通过App函数内部的数组分解来使用它们。

因此,在幕后,该钩子看起来像(只是一个伪代码):

function useState(defaultValue) {
  let value = defaultValue;

  function setValue(val) {
    value = val;
  }

  return [value, setValue];
}

当您在JS中尝试此方法时,它将无法正常工作-
如果您在setValue某处使用,从数组分解的值将不会更新。即使您将value用作对象,也不能使用Primitive defaultValue

我的问题是挂钩机制在JS中如何工作?

从我在React
源代码中看到的内容来看,它使用reducer函数和对Flow进行类型检查。对于我来说,要理解全局,代码很棘手。

这个问题不是关于如何在React中编写自定义钩子


阅读 209

收藏
2020-07-22

共1个答案

小编典典

您必须将值存储在函数外部,以便在调用之间返回持久性结果。另外,设置该值必须在其调用的组件上重新渲染:

 // 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);

然后,在setValue被调用时,组件useState将重新渲染,然后将再次被调用,并且将返回新值。

2020-07-22