美文网首页
React Hook原理初探

React Hook原理初探

作者: 是素净呀丶 | 来源:发表于2020-03-06 15:08 被阅读0次

本篇文章旨在用 最简单的代码 解释React Hook的 基础原理

  1. UseState
const hooks = [];
let index = 0;
const useState = (initial) => {
  const value = hooks[index] || initial;
  const setValue = ((i) => (newVal) => {
    if (hooks[i] === newVal) {
      return
    }
    
    hooks[i] = newVal;
    render();
  })(index);
  index += 1;
  
  return [ value, setValue ];
}

function App() {
  const [name, setName] = useState("apple");
   
  //if (name === "tangerine") {
    //const [other, setOther] = useState(10);
    //console.log(`other ---> ${other}`)
 //}

  const [age, setAge] = useState(20);
  
  setTimeout(() => {
    setName("tangerine");
    setAge(24);
  }, 2000)

  return `My Name Is ${name}, My Age Is ${age}`;
}

function render() {
  // 重置index
  index = 0;
  document.body.innerHTML = App();
}

render();

执行以上代码,视图发生了变化My Name Is apple, My Age Is 20 ---> My Name Is tangerine, My Age Is 24
原理解析:利用数组存储了所有状态变量,index代表的是变量在数组中的顺序。当调用setValue方法改变状态值时,会重新执行整个组件函数,并在之前会重置index0,原因在于重新执行组件函数时会再次依照状态变量的申明顺序去hooks中去获取值。
基于以上,便可理解为何不能在条件语句中申明状态变量,如:

if (***) {
  const [ sex ] = useState("male")
}

条件的变动会影响状态变量的顺序读值,即hooks中的index出现混乱。可将上述代码中注释部分放开,测试结果。

  1. UseEffect
const hooks = [];
const cbs = [];
let index = 0;
const useState = (initial) => {
  const value = hooks[index] || initial;
  const setValue = ((i) => (newVal) => {
    if (hooks[i] === newVal) {
      return
    }
    
    hooks[i] = newVal;
    render();
  })(index);
  index += 1;
  
  return [ value, setValue ];
}
const useEffect = (cb, deps) => {
  if (!deps) {
    cbs.push(cb);

    return;
  }

  const lastDeps = hooks[index];
  const isChanged = !lastDeps ? true : !lastDeps.every((item, index) => item === deps[index]);
  if (isChanged) { 
    cbs.push(cb);
    hooks[index] = deps;
  }
  index += 1;
}

function App() {
  const [name, setName] = useState("apple");
  const [age, setAge] = useState(20);
  
  useEffect(() => {
    console.log("no deps", document.body.innerHTML);
  });

  useEffect(() => {
    console.log(`name is ${name}`)
  }, [name]);

  useEffect(() => {
    console.log(`age is ${age}`)
  }, [age])

  setTimeout(() => {
     setName("tangerine")
  }, 2000);

  return `My Name Is ${name}, My Age Is ${age}`;
}

function render() {
  // 重置index
  index = 0;
  document.body.innerHTML = App();

  while(cbs.length) {
    cbs.splice(0, 1)[0]();
  }
}

render();

执行以上代码,视图发生了变化My Name Is apple, My Age Is 20 --> My Name Is tangerine, My Age Is 20。控制台依次打印出no deps My Name Is apple, My Age Is 20name is appleage is 20no deps My Name Is tangerine, My Age Is 20name is tangerine,可以发现useEffect包裹的函数会在render渲染完成之后执行一遍,对应生命周期componentDidMount。当状态变量name发生变化时,无依赖函数和依赖name函数会执行。
原理解析:利用数组存储了useEffect函数依赖项,执行useEffect函数时,如果没有依赖项,将其参数函数放进队列;如果有依赖项,会找到其依赖项上次状态与此次状态加以比较,如果发生了变化,将其参数函数放进队列。在渲染完成后执行队列任务并 清空

相关文章

  • React Hook原理初探

    本篇文章旨在用 最简单的代码 解释React Hook的 基础原理。 UseState 执行以上代码,视图发生了变...

  • React 初探之 Hook

    概述 Hook 使你在非 class 的情况下可以使用更多的 React 特性。Hook 是一些可以在函数组件里钩...

  • React hook 10种 Hook

    React hook 10种 Hook (详细介绍及使用) React Hook是什么?React官网是这么介绍的...

  • 学习react hook的总结

    react16推出了react hook,react hook使得functional组件拥有了class组件的一...

  • react-hook-form使用

    官网地址:https://react-hook-form.com/[https://react-hook-form...

  • react hook介绍

    react hook是什么 react hook是react中引入新特性,它可以让react函数组件也拥有状态;通...

  • React Hook介绍与使用心得

    关于React Hook React Hook 对于React来说无疑是一个伟大的特性,它将React从类组件推向...

  • React Native初探(三)- Mac

    在React Native初探(一) - Mac和React Native初探(二)- Mac中,很简陋但是能用的...

  • React Hook

    Through 4 questions introduce React Hook What is Hook? In...

  • react-hook

    react-hook

网友评论

      本文标题:React Hook原理初探

      本文链接:https://www.haomeiwen.com/subject/dnuvrhtx.html