React 导学课2

useContext()

上下文hook,接受一个上下文对象,并返回当前上下文

创建上下文:

import { createContext } from 'react';

const MyContext = createContext('default');
//这里的值是最终的保底值,根据业务类型放个默认值

当前上下文的值由树中调用组件上方的value最近的 prop确定

<MyContext.Provider value = {???}>
    {/* 这里的value是想赋给上下文Provider标签域内的value */}
    <Component1 />
    <Component2 />
</MyContext.Provider>

当最近的MyContext.Provider组件更新时,此hook将触发更新并重新渲染,并将最近的上下文value传递给MyContex提供程序,重新渲染的话仍然会从组件本身开始使用useContext。

useContext里同时可以传入函数:

  const [textContext, setTextContext] = useState('123')

  return (
    <MyContext.Provider value={[textContext, setTextContext]}>
          {/* 此时Parent组件便可以使用useContext接收到两个参数:初始值('123')和函数setTextContext */}
      <Parent />
    </MyContext.Provider>
  )

useContext()总是在调用它的组件上方寻找最近的提供者。它向上搜索并且不考虑您从中调用的组件中的提供程序useContext()

所以要小心你的provider是否嵌套,看一个demo试试

useRef()

const ref = useRef(initialValue)

useRef在组件的顶层调用以声明一个或多个refs

useRef返回一个具有单个属性的ref 对象,该属性最初设置为您提供的初始值。current

import { useRef } from 'react';


function Stopwatch() {
  const intervalRef = useRef(0);
  // ...

通过使用 ref,您可以确保:

更改 ref 不会触发重新渲染,因此 ref 不适合存储显示类的信息。

import { useRef } from 'react';

export default function Counter() {
  let ref = useRef(0);

  function handleClick() {
    ref.current = ref.current + 1;
    alert('You clicked ' + ref.current + ' times!');
  }

  return (
    <button onClick={handleClick}>
      Click me!
    </button>
  );
}

使用 ref 操作 DOM

使用 ref 来操作DOM尤其常见。React 对此有内置支持

首先,声明一个初始值为的ref 对象:null

然后将您的 ref 对象作为ref属性传递给您要操作的 DOM 节点的 JSX:

import { useRef } from 'react';

function MyComponent() {
  const inputRef = useRef(null);
  // ...
  return <input ref={inputRef} />;
}
function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}

正因为对DOM的操作频繁,我们更希望在一次使用后继续保存ref对象。所以我建议初始化以null初始,然后用if对ref做判断之后再,创建对象或赋值

function Video() {
  const playerRef = useRef(null);
	//而不是一开始就创建useRef(new VideoPlayer())
  function getPlayer() {
    if (playerRef.current !== null) {
      return playerRef.current;
    }
    const player = new VideoPlayer();
    playerRef.current = player;
    return player;
  }

组件内传递Ref

import { forwardRef } from 'react';

const MyInput = forwardRef(({ value, onChange }, ref) => {
  return (
    <input
      value={value}
      onChange={onChange}
      ref={ref}
    />
  );
};
//父组件中:
//const inputRef = useRef(null);
// return <MyInput ref={inputRef} />

export default MyInput;