React Hook相关知识点

useState 相关知识点

useState 返回的更新数据函数被调用后,不会立刻拿到最新的结果

const DemoState = (props) => {
   /* number 为此时 state 读取值 ,setNumber 为派发更新的函数 */
   let [number, setNumber] = useState(0) /* 0为初始值 */
   return (<div>
       <span>{ number }</span>
       <button onClick={ ()=> {
         setNumber(number + 1);
         console.log(number); /* 这里的 number 是不能够及时改变的  */
       } } ></button>
   </div>)
}

在函数组件中依次执行上下文中,state的值是固定不变的

function Index(){
    const [ number, setNumber ] = React.useState(0)
    const handleClick = () => setInterval(()=>{
        // 此时 number 一直都是 0
        setNumber(number + 1 ) 
    },1000)
    return <button onClick={ handleClick } > 点击 { number }</button>
}
function Index(){
    const [ number, setNumber ] = React.useState(0)
    const handleClick = () => setInterval(()=>{
        // 此时 number 一直都是 0
        setNumber(number + 1 ) 
    },1000)
    return <button onClick={ handleClick } > 点击 { number }</button>
}

当使用 useState 返回的函数修改引用数据类型时,如何保证页面渲染?

由于React官方在设计Hook时候,规定使用useState创建的数据,修改时,不像React类组件中那天,去合并原来的数据,而是直接完全替换原数据。

  • 使用展开运算符来合并更新对象
  • JSON.parse(JSON.stringify(‘引用类型变量’ )) 进行数据的深拷贝

当使用 useState 返回的函数修改基本数据类型时,如果值相同,页面是否会重新渲染?

  • 不会重新渲染,但是如果是事件中修改了值,前后不一样, 事件执行两次以上会执行render两次 。

如何获取最新修改后的数据。

  • 作为参数传递出去
  • 使用 useEffect() 监听 state 变化
  • 自定义 hook(回调函数)

useEffect 如何保证首次加载组件时执行,后续加载组件不执行回调函数

  • 添加空依赖项

useEffect 如何实现组件数据更新时的调用

  • 将需要更新的数据添加到依赖项中

useEffect 如何实现组件卸载时的清理工作

  • 添加 return 方法,并添加空依赖项

如果 useEffect 内部使用了外部的函数或者数据 state ,但是没有在依赖项里做出设置,会出现什么情况。如何解决

  • 尽可能将函数声明放在 useEffect 的内部,这样就不会构成闭包,从而解决控制台的警告,此时依赖项是无需操作的。
  • 如果一些公共的函数确实需要在其他的函数中使用,比如公共的请求,公共的工具性函数,此时可以将函数声明继续放在 useEffect 的内部,同时使用 useRef 的 current 属性保存这个函数,那么其它函数中就可以使用 current 来获取这个公共的内容进行调用。
  • 如果公共函数确实需要放在 useEffect 内部,那此时在 useEffect 内部就会形成闭包环境,控制台会发出警告,让去设置依赖项,但是不能设置依赖项,可能会造成外部函数死循环调用,可以使用 useCallback 对公共函数进行缓存,将缓存后的函数放在依赖项中,从而解决警告,又可以避免外部函数形成死循环调用

说一下 useContext 的作用,和工作方式

  • useContext 可以帮助我们跨越组件层级直接传递变量,实现共享
  1. 第一步父组件使用 React.createContext() 创建 Context 对象:
    const myContext = React.createContext(null);
  2. 使用 Context 对象.Provider 包裹子组件,使用 value 属性传值:
    <myContext.Provider value={{ setNum, num }}> <Child></Child> </myContext.Provider>
  3. 子组件使用 useContext 获取传入的值:
    const { setNum, num } = useContext(myContext);

Hooks 中的组件渲染优化相关

React.memo 的特性

  • 它类似于类组件中的 PureComponent,可以对父组件传递过来的 prop 数据是否发生改变进行浅层比较,如果 prop 发生了改变就渲染子组件,prop 没有发生改变,子组件就不会渲染。
  • 它只对比 prop,不会对当前组件的 state 进行对比

useCallback 的特性

  • 它会对函数进行缓存,返回缓存后的函数。
  • 当父组件的函数需要传递给子组件进行子组件向父组件传值时,由于传递的是普通函数,当父组件渲染时,会重新生成一个新函数,此时子组件的 React.memo 就不起作用了,需要使用 useCallback 将缓存后的函数传递过去,React.memo 才能发挥作用。
  • 当组件内的某个函数必须要作为依赖项时,需使用 useCallback 进行缓存。

useMemo 的作用

  • 它的第一个参数是函数,这个函数的返回值就是 useMemo() 要缓存的结果,一旦结果被缓存,后续组件中有连续使用这个结果的时候,直接读取缓存的值,不会重新计算。

useRef 的作用

  • 用于操作 DOM。
  • 充当全局的公共变量,保存任意数据至 current 中。且 useRef 每次返回的都是上一次修改的最新数据,不管组件如何渲染,current 里面的数据都不会重新初始化。

useReducer 的作用

  • 以redux工作流的形式,来维护当前组件的数据声明及修改功能。是useState的替代方案。

是否使用过 useReducer 搭配 useContext 来自己封装一个类似于 Redux 的公共状态管理的工具。

  1. 使用 createContext 创建 context,其中初始化了 state的类型 和 actions的种类
export const initState = {
  color: "blue"
};

export const ColorContext = createContext({
  state: initState,
  actions: {
    updateColor: (color: string): void => {}
  }
});
  1. 创建 reducer 去处理不同类型的 action
export enum ColorActionTypes {
  UPDATE_COLOR = "UPDATE_COLOR"
}

export const reducer = (state, action) => {
  switch (action.type) {
    case ColorActionTypes.UPDATE_COLOR:
      return {
        ...state,
        color: action.color
      };
    default:
      return state;
  }
};
  1. 构建一个高阶的Provider组件,使用 useReducer 去构建初始状态并获取到 dispatch 函数,使用 dispatch 函数去发送不同的 action 到 reducer 对状态进行自动处理
import { FC, useReducer } from "react";

import { ColorContext, reducer, initState, ColorActionTypes } from "./utils";

const ColorProvider: FC = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, initState);
  const updateColor = (color: string) =>
    dispatch({
      type: ColorActionTypes.UPDATE_COLOR,
      color
    });
  const actions = {
    updateColor
  };
  return (
    <ColorContext.Provider value={{ state, actions }}>
      {children}
    </ColorContext.Provider>
  );
};

export default ColorProvider;
  1. 自定义一个hook,里面使用 useContext 获取到 state 和 actions,根据场景抛出某些 state 和 某些 actions
export const useColorContext = () => {
  const { state, actions } = useContext(ColorContext);
  const updateColor = (color) => actions.updateColor(color);
  return {
    color: state.color,
    updateColor
  };
};
  1. 在项目主入口文件使用高阶的Provider组件进行包裹,另外在需要使用 state 和 actions 的地方调用自定义的 hook 即可
export default function App() {
  return (
    <div className="App">
      <ColorProvider>
        <Text />
        <Button />
      </ColorProvider>
    </div>
  );
}

Button 组件导入 useColorContext 使用 updateColor action去更新状态

import React from "react";

import { useColorContext } from "./utils";

const Button = (props) => {
  const { updateColor } = useColorContext();
  return (
    <div>
      <button
        style={{ color: "red" }}
        onClick={() => {
          updateColor("red");
        }}
      >
        Red
      </button>
      <button
        style={{ color: "blue" }}
        onClick={() => {
          updateColor("blue");
        }}
      >
        Blue
      </button>
    </div>
  );
};

export default Button;

Text 组件导入 useColorContext, 使用 color 状态

import React from "react";
import { useColorContext } from "./utils";

const Text = (props) => {
  const { color } = useColorContext();
  return <div style={{ color: color }}>字体颜色为:{color}</div>;
};

export default Text;

useImperative 的作用

  • 搭配 forwardRef,可以实现子组件向父组件暴漏方法和属性,让父组件可以直接使用子组件的属性和方法。

react 路由中都提供了哪些 hooks 的用法。各自的作用是什么。如何使用。

  • useNavigate:可以重定向
  • useLocation:获取 location 对象
  • useSearchParams:设置 url 中的查询参数
  • useParams:获取动态路由参数值

redux 中提供了哪些 hooks 的用法。各自的作用是什么。如何使用。

  • useSelector():从 Redux 存储状态中提取数据
  • useDispatch():从 Redux 存储中返回对函数的引用,使用它来调度操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值