0%

React快速上手指南

React简介

React是一个UI组件库,核心部分解决的就是声明式渲染和组件问题。

什么是声明式?

声明式编程是一种编程范式,它关注的是你要做什么,而不是如何做。它表达逻辑而不显式地定义步骤也就是说它没有描述具体的步骤。声明式编程的例子有HTML、SQL等。声明式就好像你去饭店点菜,你只需要告诉服务员你吃什么,并不需要关心后厨是怎么做的。

什么是命令式?

命令式是与声明式相对的,声明式描述了应该做什么,而命令式是描述了如何做。它会具体的描述每一个步骤。命令式就像自己照着食谱做饭,先洗菜,切菜,倒油,炒它,加调料,装盘。精确地定义好每一步,然后去实施。

什么是函数式编程?

函数式是声明式的一部分,既然是声明式的一部分,函数式也更加强调程序执行的结果而非执行的过程。JavaScript中的函数是第一类公民,就意味着函数跟其它的数据类型一样处于平等的地位,可以赋值给其他变量,可以作为参数传入另一个函数,也可以作为别的函数的返回值(这就是高阶函数)。函数式编程的目的是使用函数来抽象作用在数据之上的控制流和操作,从而在系统中消除副作用并减少对状态的改变。
我们可以看一下函数式的几个重要的概念。

不可变数据

在函数式编程中,不能更改数据。如果要改变或者更改数据,则必须复制数据副本来更改。

纯函数,拒绝副作用

纯函数实际上就是,没有副作用的函数,相同的输入有相同的输出。

引用透明

函数的返回值只依赖于其输入值。

React走的就是函数式宗教,在React声明式渲染中,有一个公式就是UI = render(data)开发者只需要维护可变的数据,React会帮助我们处理具体的DOM操作。

JSX

JSX是学习React必须知道的一个概念,JSX是一个语法糖,它既不是字符串也不是HTML,它是JavaScript的语法扩展。它就像一个拥有JavaScript所有功能的模板引擎。
React UI与逻辑 高耦合。与传统的html、css、js三种语言分在三种不同的文件里面不同。React根据同一件事,把实现这个功能的所有代码集中在一个文件里。

JSX中的onClick事件与HTML的onclick的处理方式有很大的不同。

JSX最终会通过Babel转译成为一个名为React.createElement()的函数调用。这就是为什么只要使用JSX就必须import React。

JSX防止注入攻击
React DOM 在渲染所有输入内容之前,默认会进行转义。它可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(cross-site-scripting, 跨站脚本)攻击。

元素的渲染。

React 元素是创建开销极小的普通对象。React DOM会负责更新DOM来与React元素保持一致。React只更新它需要更新的部分,ReactDOM会将元素和它的子元素的状态进行比较,只会进行必要的更新。

render

想要把一个React元素渲染到根DOM节点中,只需要把它们一起传入ReactDOM.render();
ReactDOM.render(element, container[, callback])
在container里渲染一个React元素,callback是可选的。将在组件渲染或者更新之后被执行。

render会控制你传入容器节点里的内容。当首次调用时,容器节点里的所有DOM元素都会被替换点。但是不会修改容器节点。
会返回对根组件ReactComponent实例的引用。但是要避免使用返回的引用。因为之后React版本中,组件渲染在某些情况下可能是异步的。

unmountComponentAtNode()

ReactDOM.unmountComponentAtNode(container)
从DOM中卸载组件,会将其event handlers和state一并清除。如果组件被移除返回true,如果没有组件可被移除将会返回false。

createPortal

Portals 提供了一种很好的将子节点渲染到父组件以外的 DOM 节点的方式。
ReactDOM.createPortal(child, container)
第一个参数是任何可渲染的React子元素,第二个参数则是一个DOM元素。

函数组件与class组件。

组件是React中重要的概念。这样就允许将你的UI拆分为独立可复用的代码片段。之前我们介绍过React的核心就是UI=render(data), 它接收任意的props,返回用于展示内容的React元素。而React中定义组件的两种方式

  1. 函数组件

    1
    2
    3
    function Welcome(props) {
    return <h1>Hello, {props.name}</h1>
    }
  2. 用ES6的class来定义组件

    1
    2
    3
    4
    5
    class Welcome extends React.Component {
    render() {
    return <h1>Hello, {this.props.name}</h1>
    }
    }

Props

讲到组件就离不开props。props的定义是,当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 “props”。
通过定义我们可以知道,通过props可以获得两个东西,一是组件的属性,二是子组件。

<Component name="name"> // props.name 来取得name属性上的值
    <SubComponent> // props.children 来获取子组件
</Component>

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

State

State是私有的,并且完全受控于当前组件。state 为局部的或是封装的的原因。除了拥有并设置了它的组件,其他组件都无法访问。他与props类似,它的更改会触发reRender。
在使用state的时候要注意以下几点。

  • 不要直接修改State
    直接修改State,代码不会重新渲染组件。
    应该使用setState();
  • State的更新可能是异步的
    这点很重要,因为this.props和this.state可能会异步更新,所以不要依赖他们的值来更新下一个状态。
    要是解决这个问题,可以让setState接收一个函数,而不是对象。这个函数第一个参数是上一个state,此次更新被应用时的props做为第二个参数。
  • State的更新会被合并
    简单地说就是,state中包含多个独立的变量,可以在setState中单独个更新它们,setState中只用写其中的一个变量。它会完整保留其他变量,并完全替换了你要单独改变的变量。