前端面试题 - 27. 用hook都遇到过哪些坑?

105 阅读2分钟

1. 只能在顶层使用 Hook

以下是一个错误的示例,因为在条件语句中使用了 useState:

function Example() {
  if (condition) {
    const [count, setCount] = useState(0);
    // ...
  }
  // ...
}

以下是一个正确的示例,将条件语句提取到子组件中:

function Counter() {
  const [count, setCount] = useState(0);
  // ...
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}
function Example() {
  if (condition) {
    return <Counter />;
  }
  // ...
}

2. 使用 useEffect 时需要注意依赖项

以下是一个错误的示例,因为依赖项数组中没有给出任何依赖项:

function Example() {
  useEffect(() => {
    // ...
  }, []);
  // ...
}

以下是一个正确的示例,给出了一个依赖项数组:

function Example({ id }) {
  useEffect(() => {
    fetchData(id);
  }, [id]);
  // ...
}

3. 使用 useState 时需要注意函数更新的问题:

以下是一个错误的示例,因为使用了错误的函数更新方式:

function Example() {
  const [count, setCount] = useState(0);
  // ...
  const handleClick = () => {
    setCount(count + 1); // 错误的函数更新方式
  };
  // ...
}

以下是一个正确的示例,使用正确的函数更新方式:

function Example() {
  const [count, setCount] = useState(0);
  // ...
  const handleClick = () => {
    setCount((prevCount) => prevCount + 1); // 正确的函数更新方式
  };
  // ...
}

4. 使用 useCallback 时需要注意依赖项的问题:

以下是一个错误的示例,因为 useCallback 中的依赖项数组中没有给出任何依赖项:

function Example() {
  const handleClick = useCallback(() => {
    // ...
  }, []);
  // ...
}

以下是一个正确的示例,给出了一个依赖项数组:

function Example({ id }) {
  const handleClick = useCallback(() => {
    fetchData(id);
  }, [id]);
  // ...
}

5. 使用 useRef 时需要注意 ref 对象的问题:

以下是一个错误的示例,因为使用了 ref 对象,而不是 ref.current:

function Example() {
  const inputRef = useRef(null);
  // ...
  const handleClick = () => {
    inputRef.focus(); // 错误的使用方式
  };
  // ...
}

以下是一个正确的示例,使用了 ref.current:

function Example() {
  const inputRef = useRef(null);
  // ...
  const handleClick = () => {
    inputRef.current.focus(); // 正确的使用方式
  };
  // ...
}

6. 使用 useContext 时需要注意传递的值:

以下是一个错误的示例,因为传递的值是可变的:

const UserContext = React.createContext({});
function Example() {
  const user = { name: "Tom", age: 18 };
  return (
    <UserContext.Provider value={user}>
      <UserInfo />
    </UserContext.Provider>
  );
}

以下是一个正确的示例,传递的值是不可变的:

const UserContext = React.createContext({});
function Example() {
  const user = useMemo(() => ({ name: "Tom", age: 18 }), []);
  return (
    <UserContext.Provider value={user}>
      <UserInfo />
    </UserContext.Provider>
  );
}