加入收藏 | 设为首页 | 会员中心 | 我要投稿 汽车网 (https://www.0577qiche.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

搭配 React介绍

发布时间:2023-04-06 13:58:01 所属栏目:教程 来源:
导读:这里需要再强调一下:Redux 和 React 之间没有关系。Redux 支持 React、Angular、Ember、jQuery 甚至纯 JavaScript。

尽管如此,Redux 还是和 React 和 Deku 这类库搭配起来用最好,因为这类库允许你以 state 函数
这里需要再强调一下:Redux 和 React 之间没有关系。Redux 支持 React、Angular、Ember、jQuery 甚至纯 JavaScript。

尽管如此,Redux 还是和 React 和 Deku 这类库搭配起来用最好,因为这类库允许你以 state 函数的形式来描述界面,Redux 通过 action 的形式来发起 state 变化。

下面使用 React 来开发一个 todo 任务管理应用。

安装 React Redux
Redux 默认并不包含 React 绑定库,需要单独安装。

npm install --save react-redux
如果你不使用 npm,你也可以从 unpkg 获取最新的 UMD 包(包括开发环境包和生产环境包)。如果你用 <script> 标签的方式引入 UMD 包,那么它会在全局抛出window.ReactRedux对象。

容器组件(Smart/Container Components)和展示组件(Dumb/Presentational Components)
Redux 的 React 绑定库是基于 容器组件和展示组件相分离 的开发思想。所以建议先读完这篇文章再回来继续学习。这个思想非常重要。

已经读完了?那让我们再总结一下不同点:

展示组件    容器组件
作用    描述如何展现(骨架、样式)    描述如何运行(数据获取、状态更新)
直接使用 Redux    否    是
数据来源    props    监听 Redux state
数据修改    从 props 调用回调函数    向 Redux 派发 actions
调用方式    手动    通常由 React Redux 生成
大部分的组件都应该是展示型的,但一般需要少数的几个容器组件把它们和 Redux store 连接起来。这和下面的设计简介并不意味着容器组件必须位于组件树的最顶层。如果一个容器组件变得太复杂(例如,它有大量的嵌套组件以及传递数不尽的回调函数),那么在组件树中引入另一个容器,就像FAQ中提到的那样

技术上讲你可以直接使用 store.subscribe() 来编写容器组件。但不建议这么做的原因是无法使用 React Redux 带来的性能优化。也因此,不要手写容器组件,而使用 React Redux 的 connect() 方法来生成,后面会详细介绍。

设计组件层次结构
还记得当初如何设计state根对象的结构 吗?现在就要定义与它匹配的界面的层次结构。其实这不是 Redux 相关的工作,React 开发思想在这方面解释的非常棒。

我们的概要设计很简单。我们想要显示一个 todo 项的列表。一个 todo 项被点击后,会增加一条删除线并标记 completed。我们会显示用户新增一个 todo 字段。在 footer 里显示一个可切换的显示全部/只显示 completed 的/只显示 incompleted 的 todos。

展示组件
以下的这些组件(和它们的 props )就是从这个设计里来的:

TodoList 用于显示 todos 列表。

todos: Array 以 { text, completed } 形式显示的 todo 项数组。

onTodoClick(index: number) 当 todo 项被点击时调用的回调函数。

Todo 一个 todo 项。

text: string 显示的文本内容。

completed: boolean todo 项是否显示删除线。

onClick() 当 todo 项被点击时调用的回调函数。

Link 带有 callback 回调功能的链接

onClick() 当点击链接时会触发

Footer 一个允许用户改变可见 todo 过滤器的组件。

App 根组件,渲染余下的所有内容。

这些组件只定义外观并不关心数据来源和如何改变。传入什么就渲染什么。如果你把代码从 Redux 迁移到别的架构,这些组件可以不做任何改动直接使用。它们并不依赖于 Redux。

容器组件
还需要一些容器组件来把展示组件连接到 Redux。例如,展示型的 TodoList 组件需要一个类似 VisibletodoList 的容器来监听 Redux store 变化并处理如何过滤出要显示的数据。为了实现状态过滤,需要实现 FilterLink 的容器组件来渲染 Link 并在点击时触发对应的 action:

VisibletodoList 根据当前显示的状态来对 todo 列表进行过滤,并渲染 TodoList。

FilterLink 得到当前过滤器并渲染 Link。

filter: string 就是当前过滤的状态

其它组件
有时很难分清到底该使用容器组件还是展示组件。例如,有时表单和函数严重耦合在一起,如这个小的组件:

AddTodo 含有“Add”按钮的输入框

技术上讲可以把它分成两个组件,但一开始就这么做有点早。在一些非常小的组件里混用容器和展示是可以的。当业务变复杂后,如何拆分就很明显了。所以现在就使用混合型的吧。

组件编码
终于开始开发组件了!先做展示组件,这样可以先不考虑 Redux。

实现展示组件
它们只是普通的 React 组件,所以不会详细解释。我们会使用函数式无状态组件除非需要本地 state 或生命周期函数的场景。这并不是说展示组件必须是函数 -- 只是因为这样做容易些。如果你需要使用本地 state,生命周期方法,或者性能优化,可以将它们转成 class。

components/Todo.js
import React from 'react'
import PropTypes from 'prop-types'
 
const Todo = ({ onClick, completed, text }) => (
  <li
    onClick={onClick}
    style={{
      textdecoration: completed ? 'line-through' : 'none'
    }}
  >
    {text}
  </li>
)
 
Todo.propTypes = {
  onClick: PropTypes.func.isrequired,
  completed: PropTypes.bool.isrequired,
  text: PropTypes.string.isrequired
}
 
export default Todo
components/TodoList.js
import React from 'react'
import PropTypes from 'prop-types'
import Todo from './Todo'
 
const TodoList = ({ todos, onTodoClick }) => (
  <ul>
    {todos.map((todo, index) => (
      <Todo key={index} {...todo} onClick={() => onTodoClick(index)} />
    ))}
  </ul>
)
 
TodoList.propTypes = {
  todos: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.number.isrequired,
      completed: PropTypes.bool.isrequired,
      text: PropTypes.string.isrequired
    }).isrequired
  ).isrequired,
  onTodoClick: PropTypes.func.isrequired
}
 
export default TodoList
components/Link.js
import React from 'react'
import PropTypes from 'prop-types'
 
const Link = ({ active, children, onClick }) => {
  if (active) {
    return <span>{children}</span>
  }
 
  return (
    <a
      href=""
      onClick={e => {
        e.preventDefault()
        onClick()
      }}
    >
      {children}
    </a>
  )
}
 
Link.propTypes = {
  active: PropTypes.bool.isrequired,
  children: PropTypes.node.isrequired,
  onClick: PropTypes.func.isrequired
}
 
export default Link
components/Footer.js
import React from 'react'
import FilterLink from '../containers/FilterLink'
 
const Footer = () => (
  <p>
    Show: <FilterLink filter="SHOW_ALL">All</FilterLink>
    {', '}
    <FilterLink filter="SHOW_ACTIVE">Active</FilterLink>
    {', '}
    <FilterLink filter="SHOW_COMPLETED">Completed</FilterLink>
  </p>
)
 
export default Footer

现在来创建一些容器组件把这些展示组件和 Redux 关联起来。技术上讲,容器组件就是使用 store.subscribe() 从 Redux state 树中读取部分数据,并通过 props 来把这些数据提供给要渲染的组件。你可以手工来开发容器组件,但建议使用 React Redux 库的 connect() 方法来生成,这个方法做了性能优化来避免很多不必要的重复渲染。(这样你就不必为了性能而手动实现 React 性能优化建议 中的 shouldComponentUpdate 方法。)

(编辑:汽车网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章