React 核心概念

JSX

JSX 是一个表达式,JSX的值是一个JS对象,因此可以再if for代码块中使用JSX,也可以将JSX赋给变量或把JSX当作参数传入,以及从函数中返回JSX

JSX 最终会被编译为 React.createElement() 函数调用,返回称为 “React 元素” 的普通 JavaScript 对象

元素渲染

React元素是开销极小的普通对象,React DOM 会负责更新DOM来与React元素保持一致

更新已渲染的元素:

React元素是不可变对象,更新UI的唯一方式是创建一个全新的元素,重新ReactDOM.render()

React 只更新它需要更新的部分

React DOM 会将元素和它的子元素与它们之前的状态进行比较,并只会进行必要的更新来使 DOM 达到预期的状态。

组件 & Props

定义组件两种方式:

通过JS函数:

function Welcome(props) {
  return 

Hello, {props.name}

; }

通过ES6 的 class:

class Welcome extends React.Component {
  render() {
    return 

Hello, {this.props.name}

; } }

如何选择:如果你想写的组件只包含一个 render 方法,并且不包含 state,那么使用函数组件就会更简单。

注意: 组件名称必须以大写字母开头。
React 会将以小写字母开头的组件视为原生 DOM 标签

渲染组件:

const element = ;

关于提取组件:

何时需要将组件拆分为更下的组件?

如果 UI 中有一部分被多次使用(Button,Panel,Avatar),或者组件本身就足够复杂(App,FeedStory,Comment),那么它就是一个可复用组件的候选项。

Props 的只读性:

首先了解下纯函数的定义:即不会更改入参的函数。

React 组件都必须像纯函数一样保护它们的 props 不被更改

State & 生命周期

State与生命周期的使用需要在class组件中。

State 与 props 类似,但是 state 是私有的,并且完全受控于当前组件。

使用this.setState() 来更新组件 state, 这时React会重新调用render()

生命周期:

componentDidMount() 在组件已经被渲染到 DOM 中后运行

componentWillUnmount() 组件被删除前

注意的几个点:

构造函数是唯一可以给 this.state 赋值的地方

State 的更新可能是异步的

出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用。
因为 this.props 和 this.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。

事件处理

React 中你不能通过返回 false 的方式阻止默认行为,必须显式的使用 preventDefault。

e 是一个合成事件。React 根据 W3C 规范来定义这些合成事件,所以你不需要担心跨浏览器的兼容性问题

表单

React 中,HTML 表单元素的工作方式和其他的 DOM 元素有些不同,表单元素通常会保持一些内部的 state。

受控组件(类似vue中使用:value或v-model绑定数据):

  1. React 的 state 成为“唯一数据源”。
  2. 渲染表单的 React 组件控制着用户输入过程中表单发生的操作。

文件input标签 非受控组件,因为它的value只读。

状态提升

多个组件中需要共享的 state 向上移动到它们的最近共同父组件中,便可实现共享 state。这就是所谓的“状态提升”。
即通过自上而下的数据流,将state放入父组件通过props传入子组件。

状态提升 vs 双向绑定

提升 state 方式比双向绑定方式需要编写更多的“样板”代码,但带来的好处是,排查和隔离 bug 所需的工作量将会变少。由于“存在”于组件中的任何 state,仅有组件自己能够修改它,因此 bug 的排查范围被大大缩减了。

组合 vs 继承

父组件中的所有内容内容都会作为名为childrenprop传递给子组件

React vs Vue

Vue: 使用slot。
React: 没有slot槽的概念,因为React 元素本质就是对象,所以一切都可通过props传入子组件。

React 哲学

React 最棒的部分之一是引导我们思考如何构建一个应用。

用React 哲学实现一个可搜索数据表格

第一步:划分组件层级

根据单一功能原则划分组价你的范围,一个组件原则上只负责一个功能。

第二步:创建一个静态版本

核心思想是渲染UI和添加交互这两个过程应该分开。因为编写应用的静态版本时往往需要编写大量代码,而不需要考虑太多交互细节;添加交互功能时则要考虑大量细节,不需要写大量代码。所以这两个过程分开更为合适。

构建应用的静态版本时,使用props传数据(即使需要使用state,这一步也不应该使用state,而是把state替换props留到添加交互这一步骤中实现)

构建顺序:
你可以自上而下或者自下而上构建应用。
当你的应用比较简单时,使用自上而下的方式更方便;对于较为大型的项目来说,自下而上地构建,并同时为低层组件编写测试是更加简单的方式。

第三步:确定UI state 的最小(且完整)表示

即找到应用所需的最少数量state的表示方式,其余数据均可由它们计算产生。遵循DRY(Don't Repeat Yourself)原则

通过问自己以下三个问题,你可以逐个检查相应数据是否属于 state:

  • 该数据是否是由父组件通过 props 传递而来的?如果是,那它应该不是 state。
  • 该数据是否随时间的推移而保持不变?如果是,那它应该也不是 state。
  • 你能否根据其他 state 或 props 计算出该数据的值?如果是,那它也不是 state。

第四步:确定 state 放置的位置

你可以尝试通过以下步骤来判断

对于应用中的每一个 state:

  • 找到根据这个 state 进行渲染的所有组件。
  • 找到他们的共同所有者(common owner)组件(在组件层级上高于所有需要该 state 的组件)。
  • 该共同所有者组件或者比它层级更高的组件应该拥有该 state。
  • 如果你找不到一个合适的位置来存放该 state,就可以直接创建一个新的组件来存放该 state,并将这一新组件置于高于共同所有者组件层级的位置。

第五步:添加反向数据流

React 通过一种比传统的双向绑定略微繁琐的方法来实现反向数据传递。尽管如此,但这种需要显式声明的方法更有助于人们理解程序的运作方式。

你可能感兴趣的:(React 核心概念)