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 被传入时会使用默认参数

目录
相关文章
|
2月前
|
缓存 前端开发 JavaScript
React Hooks深度解析与最佳实践:提升函数组件能力的终极指南
🌟蒋星熠Jaxonic,前端探索者。专注React Hooks深度实践,从原理到实战,分享状态管理、性能优化与自定义Hook精髓。助力开发者掌握函数组件的无限可能,共赴技术星辰大海!
React Hooks深度解析与最佳实践:提升函数组件能力的终极指南
|
7月前
|
缓存 前端开发 数据安全/隐私保护
如何使用组合组件和高阶组件实现复杂的 React 应用程序?
如何使用组合组件和高阶组件实现复杂的 React 应用程序?
275 68
|
7月前
|
缓存 前端开发 Java
在 React 中,组合组件和高阶组件在性能方面有何区别?
在 React 中,组合组件和高阶组件在性能方面有何区别?
254 67
|
7月前
|
前端开发 JavaScript 安全
除了高阶组件和render props,还有哪些在 React 中实现代码复用的方法?
除了高阶组件和render props,还有哪些在 React 中实现代码复用的方法?
288 62
|
9月前
|
前端开发
React 中高阶组件的原理是什么?
React 中高阶组件的原理是什么?
238 57
|
9月前
|
移动开发 前端开发 JavaScript
React音频播放列表组件:常见问题、易错点与解决方案
本文介绍了在React中实现音频播放列表时常见的挑战及解决方案。通过基础实现、常见问题分析和最佳实践,帮助开发者避免状态管理、生命周期控制和事件处理中的陷阱。关键点包括使用`useRef`操作音频元素、`useState`同步播放状态、全局状态管理防止多音频同时播放、以及通过`useEffect`清理资源。还提供了代码示例和跨浏览器兼容性处理方法,确保高效实现功能并减少调试时间。
302 30
|
9月前
|
移动开发 前端开发 UED
React 音频音量控制组件 Audio Volume Control
在现代Web应用中,音频播放功能不可或缺。React以其声明式编程和组件化开发模式,非常适合构建复杂的音频音量控制组件。本文介绍了如何使用HTML5 `&lt;audio&gt;`元素与React结合,实现直观的音量控制系统,并解决了常见问题如音量范围不合理、初始音量设置及性能优化等,帮助开发者打造优秀的音频播放器。
314 27
|
9月前
|
编解码 前端开发 开发者
React 图片组件样式自定义:常见问题与解决方案
在 React 开发中,图片组件的样式自定义常因细节问题导致布局错乱、性能损耗或交互异常。本文系统梳理常见问题及解决方案,涵盖基础样式应用、响应式设计、加载状态与性能优化等,结合代码案例帮助开发者高效实现图片组件的样式控制。重点解决图片尺寸不匹配、边框阴影不一致、移动端显示模糊、加载失败处理及懒加载等问题,并总结易错点和最佳实践,助力开发者提升开发效率和用户体验。
282 22
|
9月前
|
移动开发 前端开发 开发者
React 音频播放控制组件 Audio Controls
本文介绍了如何使用React构建音频播放控制组件,涵盖HTML5 `&lt;audio&gt;`标签和React组件化思想的基础知识。针对常见问题如播放状态管理、进度条更新不准确及跨浏览器兼容性,提供了详细的解决方案和代码示例。同时,还总结了易错点及避免方法,如确保音频加载完成再操作、处理音频错误等,帮助开发者实现稳定且功能强大的音频播放器。
367 11
|
9月前
|
移动开发 前端开发 UED
React 音频进度条组件 Audio Progress Bar
在现代Web开发中,音频播放功能不可或缺。使用React构建音频进度条组件,不仅能实现播放控制和拖动跳转,还能确保代码的可维护性和复用性。本文介绍了如何利用HTML5 `&lt;audio&gt;`标签的基础功能、解决获取音频时长和当前时间的问题、动态更新进度条样式,并避免常见错误如忘记移除事件监听器和忽略跨浏览器兼容性。通过这些方法,开发者可以打造高质量的音频播放器,提升用户体验。
339 6