服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服务器之家 - 编程语言 - JavaScript - React - 从 React 新官网学到的一个优秀实践妙招

从 React 新官网学到的一个优秀实践妙招

2024-04-15 15:36这波能反杀 React

React 新的官方文档确实写得非常好,提供了许多项目开发最佳实践的思路。这些思路和实用技巧,同样也适用于 Vue,也能够提高我们对 Vue 的使用心得。

从 React 新官网学到的一个优秀实践妙招

在开发过程中,我们常常会遇到这样的场景。

有一个列表,但是我们需要根据列表的不同类型查询并显示对应类型的数据。如头图所示。这里有一个很明确的现象就是,不同的类型会对应不同的列表,但是当我们代入抽象思维思考一下就能轻易发现,除了类型不同之外,其他的所有特性都是一样的。

一样的接口、一样的 UI、一样的类型、一样的交互。因此我们很容易会想到,把多个类型的列表当成同一个列表来处理,当 type 发生变化时去重新请求接口就可以轻松完成这个功能。

function ListPage() {
  const [list, setList] = useState([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')

  const [type, setType] = useState('all')

  useEffect(() => {
    setLoading(true)
    api.get('xxx/xxx/xxx', type).then(res => {
      setList(res.data)
      setLoading(false)
      setError('')
    })
  }, [type])

  return (
    <>
      <Tabs type={type} onChange={setType} />
      <List
        list={list}
        loading={loading}
        error={error}
        renderItem={(item) => (
          <div key={item} className={s.item}>{item}</div>
        )}
      />
    </>
  )
}

这样的处理是有一定合理性的,我相信很多小伙伴也会这样处理。因为他非常符合语义。

不过 React 新官方文档中,提出了一个更巧妙的方式来解决这个问题。

首先,我们可以将列表逻辑单独拆分为一个子组件。该子组件接收参数 type 作为一个 props

function ListPart({type}) {
  const [list, setList] = useState([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')

  useEffect(() => {
    api.get('xxx/xxx/xxx', type).then(res => {
      setList(res.data)
      setLoading(false)
      setError('')
    })
  }, [])
  
  return (
    <List
      list={list}
      loading={loading}
      error={error}
      renderItem={(item) => (
        <div key={item} className={s.item}>{item}</div>
      )}
    />
  )
}

然后这里的重点来了,在 ListPage 组件中,我们在刚才封装好的子组件 ListPart 上,传入一个 key 值。这样,我们就能够在不显示监听 type 变化的情况下,做到跟刚才一样的效果。

function ListPage() {
  const [type, setType] = useState('all')
  return (
    <div>
      <Tabs type={type} onChange={setType} />
      <ListPart type={type} key={type} />
    </div>
  )
}

在 React 的 diff 过程中,当一个组件的 key 值发生了变化,那么该组件将会被重新创建。我们也正是巧妙的利用了这个内部逻辑,将代码改进成现在这样。

在 ListPart 的封装中,我们还可以借助我们之前封装自定义 hook 的思路,进一步简化代码。

function ListPart({type}) {
  const { loading, list = [], error } = useFetch(api, type)
  
  return (
    <List
      list={list}
      loading={loading}
      error={error}
      renderItem={(item) => (
        <div key={item} className={s.item}>{item}</div>
      )}
    />
  )
}

这里面由于自定义 hook useFetch 是提前封装好的工具方法,List 是提前封装好的列表组件,当我们在写页面页面时,整个列表的开发工作量将会非常小。

完整代码如下:

function ListPage() {
  const [type, setType] = useState('all')

  return (
    <div>
      <Tabs type={type} onChange={setType} />
      <ListPart type={type} key={type} />
    </div>
  )
}
function ListPart({type}) {
  const { loading, list = [], error } = useFetch(api, type)
  
  return (
    <List
      list={list}
      loading={loading}
      error={error}
      renderItem={(item) => (
        <div key={item} className={s.item}>{item}</div>
      )}
    />
  )
}

其他案例

给子组件传入 key 值,当 key 值发生变化,子组件会被重置。这样的思路还可以运用到别的类似场景。

例如,你请求了一个书籍列表,但是某一个区域只能显示选中的书籍的部分信息与几条用户评价,当我们选中别的书籍时,这信息与评论都需要全部更新。

这里处理起来比较麻烦的是书籍部分信息是从父级传递而来,而评论信息却是需要重新请求获取。

不过借助这个思路,将会非常容易做到良好的解耦,我们只需要从父级通过 props 把书籍信息传递下来,然后在子组件内部自己去处理评论信息即可。从而断开评论信息与书籍切换的耦合。

function BookProfile() {
  ...

  return (
    <div>
      ...
      <CurrentBookPart info={infolist[i]} key={bookid} />
    </div>
  )
}
function CurrentBookPart(props) {
  const [comment, setComment] = useState()
  ...
}

总结

合理运用这个技巧,可以让我们的代码更加高效、低耦合,逻辑更加顺畅。也能够大幅度提高我们的开发效率,快快去重新查看一下你的项目,有没有可以使用这种方式重构的地方吧。

React 新的官方文档确实写得非常好,提供了许多项目开发最佳实践的思路。这些思路和实用技巧,同样也适用于 Vue,也能够提高我们对 Vue 的使用心得。

原文地址:https://mp.weixin.qq.com/s/Zj2M9YvtBZhNsim9D27aTw

延伸 · 阅读

精彩推荐
  • ReactReact+Antd 实现可增删改表格的示例

    React+Antd 实现可增删改表格的示例

    这篇文章主要介绍了React+Antd实现可增删改表格的示例,帮助大家更好的理解和学习使用React,感兴趣的朋友可以了解下...

    用户3202285797826042022-02-24
  • React从 React 新官网学到的一个优秀实践妙招

    从 React 新官网学到的一个优秀实践妙招

    React 新的官方文档确实写得非常好,提供了许多项目开发最佳实践的思路。这些思路和实用技巧,同样也适用于 Vue,也能够提高我们对 Vue 的使用心得。...

    这波能反杀7742024-04-15
  • ReactReact实现todolist功能

    React实现todolist功能

    这篇文章主要介绍了React实现todolist功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...

    一杯清泉7102021-12-21
  • ReactReact为什么要废弃ComponentWillMount、ReceiveProps和Update这三个生命周期

    React为什么要废弃ComponentWillMount、ReceiveProps和Update这三个生命周

    componentWillMount 是 React 组件的生命周期方法之一,它在组件即将被挂载到 DOM 中之前被调用。在该方法中,你可以执行一些准备工作,例如初始化状态、订阅...

    海燕技术栈10892024-03-27
  • React聊一聊React 优先级队列的实现方式

    聊一聊React 优先级队列的实现方式

    《数据结构堆》一文中,跟大家分享了如何利用二叉堆实现优先级队列。这可就赶巧了,React 的优先级队列的实现方式,居然跟我书里里介绍的方法几乎一...

    这波能反杀10722024-03-12
  • ReactReact 三大属性之state的使用详解

    React 三大属性之state的使用详解

    这篇文章主要介绍了React 三大属性之state的使用详解,帮助大家更好的理解和学习使用React,感兴趣的朋友可以了解下...

    xiaoznz3992022-03-02
  • Reactreact项目如何运行在微信公众号

    react项目如何运行在微信公众号

    这篇文章主要介绍了react项目如何运行在微信公众号,帮助大家更好的理解和学习使用react,感兴趣的朋友可以了解下...

    阿凡凡没有提11202022-03-03
  • ReactNext.js vs Remix - 开发者的困境

    Next.js vs Remix - 开发者的困境

    Next.js 是最流行的用于服务器端渲染的 React 框架之一。它已经存在相当长的时间了,并且提供了开发者所需的所有功能,提供了出色的开发体验。...

    编程界10952024-03-06