记录一下自己学react的hook1.0

99 阅读3分钟

学习react已经有一段时间了,也用react自己做了一些小的项目,但是回过头来其实发现用来用去的一直都是那几个点,但是react中还是有很多的hook自己是没有用到的,一方面是自己对其的理解还不够深,不够熟练导致出现了很好的运用场景却没有想起来,而是用了更为笨拙的方法实现了,另一方面就是这些hook能适应的场景很少见,导致自己使用的很不熟练,怕自己用错,造成的问题更大,那么这样看来,要好好的整理下到底有哪些hook,这样即使自己不会用,至少当别人使用的时候自己可以看的明白。

useContext

按照字面的意思,它的作用应该和上下文有关,结合官方文档做出的解释,它的作用就是用于祖孙组件的props的传递,没了解这个hook之前,我们面对这种祖孙组件的参数参数传递的话就要一层一层的传递,如下图的极端例子:

image.png

外层的pros要传递给最里层的组件,如果一层一层的传递那么其他的组件就会接受很多不必要的props,这样肯定是不好,这时候就可以考虑一下useContext这个钩子了。

import React ,{useContext} from 'react';
const ThemeContext = React.createContext("名字");
const App = () => {
  return (
    <div>
      <ThemeContext.Provider value='张三'>
        <Test1></Test1>
      </ThemeContext.Provider>
    </div>
  );
}

const Test1 = () => {
  return (
    <div>
      <Test2></Test2>
    </div>
  );
}
const Test2 = () => {
  return (
    <div>
      <Test3></Test3>
    </div>
  );
}
const Test3 = () => {
  const Context = useContext(ThemeContext);
  return (
    <div>
      {Context}
    </div>
  );
}

export default App;

这里上下文初始化的时候的值是在子组件没有找到最近的Provider的时候就会生效。

useImperativeHandle

从字面上来说这个钩子是真的不好理解,啥迫切的处理???结合官方的例子才能看懂,这个钩子要配合forwardRef一起使用,先介绍一下啥是forwardRef,react的出现就是为了简化我们操作dom,让我们不去操作dom,而是通过他规定的一些语法就完成我们的需求,但是有时候对dom元素的操作是必须的,于是react就推出了createRefuseRef,对于react栈的这两个应该已经很熟了,这里就不做解释了,这两个api可以很好的帮我们拿到dom节点,对节点进行操作(比如啥input框获取焦点啊啥啥的),但是有的时候我们不仅仅只是操作当前组件的dom,有时候是要跨组件进行操作的,比如我的父组件需要操作子组件的input框,让其在一定的情况下进行获取焦点,那么很自然的,我们想到了,我们可以把ref传递给子组件,然后再赋值给子组件的ref上,但是ref是react的关键字就像key一样,这样的props在子组件中是获取不到的,所以这个时候forwordRef的作用的体现出来了,我们通过这个forwordRef的包装就可以让我们的父组件获取得到子组件的dom,具体代码如下:

import React,{useRef,forwardRef,useImperativeHandle} from 'react';

const App = () => {
  const myInput=useRef();
  return (
    <div>
      <FancyInput ref={myInput}></FancyInput>
      <button onClick={()=>{myInput.current.focus();console.log(myInput)}}>点我获取</button>
    </div>
  );
}
function FancyInput(props, ref) {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));
  return <input ref={inputRef} />;
}
FancyInput = forwardRef(FancyInput);
export default App;

那么这里的useImperativeHandle的作用到底是啥能,其实如果只是为了获取子组件的dom我们完全可以不需要这个钩子,这个钩子的作用是让我们可以限制父组件操作dom上的属性内容,原来父组件可以操作dom上的所有方法和属性,但是经过这个钩子之后就只能操作,我们所暴露出的内容了。