2022 React 最速上手指南(十一)—— 自定义 hook & 可复用组件

简介: 2022 React 最速上手指南(十一)—— 自定义 hook & 可复用组件

以结果为导向,写给刚学完前端三剑客和想要了解 React 框架的小伙伴,使得他们能快速上手(省略了历史以及一些不必要的介绍)。



自定义 hook


Hooks: functions starting with use — can only be called at the top level of your components or your own Hooks.


虽然 React 自带很多 hook,但肯定不能涵盖我们所有的需求,所以自定义 hook 就很重要了。


我们将 App 组件里【管理 state 并同步到本地存储的功能】抽离出来,创建一个新的自定义 hook 叫做 useSemiPersistentState ,翻译过来就是半持久化,【半】是因为清除浏览器的本地存储就会把应用所有相关数据都删掉。


const useSemiPersistentState = () => {
  const [value, setValue] = React.useState(
    localStorage.getItem("search") || "React"
  );
  React.useEffect(() => {
    localStorage.setItem("value", value);
  }, [value]);
  return [value, setValue];
};
const App = () => {
  ...
  const [searchTerm, setSearchTerm] = useSemiPersistentState();
  ...
};
复制代码


因为我们自定义 hook 的目标是【可复用性】,所以我们要用抽象的值 ”value“,而在 App 组件中调用时可以使用有业务含义的词来命名。


还有一个问题:如果在一个应用中多次调用这个 hook ,由于名字都是 “value”,会造成本地存储的值被覆盖。


可以通过传入一个 key 值解决,同时让它接收一个初始的 state:


const useSemiPersistentState = (key, initialState) => {
  const [value, setValue] = React.useState(
    localStorage.getItem(key) || initialState
  );
  React.useEffect(() => {
    localStorage.setItem(key, value);
  }, [value, key]);
  return [value, setValue];
};
const App = () => {
  ...
  const [searchTerm, setSearchTerm] = useSemiPersistentState(
    "search", "React"
  );
  ...
};
复制代码


因为 key 值来自外部,随时可能发生变化,所以要把它放入 useEffect 的依赖数组里,以防副作用使用了过期的 key 值。


这样我们就创建了第一个自定义 hook,它把复杂的实现细节包装起来,从而使组件逻辑更加清晰,并且可以【复用】到更多的 React 组件中,甚至可以作为第三方库开源出去,比如 streamich/react-usealibaba/hooksvercel/swr 等等。


可复用组件


Computer scientists use abstraction to make models that can be used and re-used without having to re-write all the program code for each new application on every different type of computer.


如果我们同时渲染两个 Search 组件,相同的 htmlFor 和 id 属性值一定会引入 bug,并且由于和搜索功能强相关,使得组件的可复用性非常差。


但该组件实际并不具备任何的 “搜索” 能力,我们可以通过传递 id 和 label 等参数将 Search 组件抽象成一个能覆盖其他搜索场景的通用组件:


const App = () => {
 ....
  return (
    <>
      <InputWithLabel
        id="search"
        label="Search"
        value={searchTerm}
        onInputChange={handleSearch}
      />
      <hr />
      <List list={searchedStories} />
    </>
  );
};
const InputWithLabel = ({ id, label, value, type = "text", onInputChange }) => (
  <>
    <label htmlFor={id}>{label}</label>
    &nbsp;&nbsp;
    <input id={id} type={type} value={value} onChange={onInputChange} />
  </>
);
复制代码


在 InputWithLabel 组件中我们指定了 type 的默认参数,在没有值或 undefined 被传入时会使用默认参数

目录
相关文章
|
前端开发
React useImperativeHandle Hook
【7月更文挑战第1天】React useImperativeHandle Hook
169 3
|
前端开发 JavaScript 数据格式
react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )
react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )
551 1
|
前端开发
React 中的 Hook 概念
【8月更文挑战第31天】
322 0
|
前端开发
Vue3 【仿 react 的 hook】封装 useTitle
Vue3 【仿 react 的 hook】封装 useTitle
223 0
|
前端开发 API
Vue3 【仿 react 的 hook】封装 useLocation
Vue3 【仿 react 的 hook】封装 useLocation
226 0
|
存储 前端开发 中间件
React组件间的通信
React组件间的通信
215 1
|
前端开发 JavaScript
【边做边学】React Hooks (二)——useEffect Hook
【边做边学】React Hooks (二)——useEffect Hook
168 0
|
前端开发 JavaScript
React中useEffect Hook使用纠错
React中useEffect Hook使用纠错
258 0
|
前端开发 应用服务中间件 数据库
react服务端组件
react服务端组件
151 0
|
6月前
|
缓存 前端开发 JavaScript
React Hooks深度解析与最佳实践:提升函数组件能力的终极指南
🌟蒋星熠Jaxonic,前端探索者。专注React Hooks深度实践,从原理到实战,分享状态管理、性能优化与自定义Hook精髓。助力开发者掌握函数组件的无限可能,共赴技术星辰大海!
React Hooks深度解析与最佳实践:提升函数组件能力的终极指南