Introduction to the React
React,由 FaceBook 普及,是一个用于构建用户界面的开源 JavaScript 库。通过 JSX 创建组件,处理 state 和 props,利用事件监听和指定的生命周期钩子动态更新数据。
React 混合了 HTML 和 JavaScript 的函数性创建了一个新的标签语言,JSX。
创建一个简单的 JSX 元素
简介:React 是由 Facebook 创建和维护的开源视图库。它是渲染当代 Web 应用程序用户界面(UI)的绝佳工具。
React 使用名为 JSX 的 JavaScript 语法扩展,允许你直接在 JavaScript 中编写 HTML。这有几个好处。它允许你在 HTML 中使用 JavaScript 的完整程序功能,并有助于保持代码的可读性。在大多数情况下,JSX 类似于已经学过的 HTML
例如,因为 JSX 是 JavaScript 的语法扩展,所以实际上可以直接在 JSX 中编写 JavaScript。要做到这一点,只需在花括号中包含你希望被视为 JavaScript 的代码:{“这被视为 JavaScript 代码”}
。
但是,由于浏览器不能解析 JSX,因此必须将 JSX 代码编译为 JavaScript。在这个过程中,转换器 Babel 是一个很受欢迎的工具。
1 | const JSX = <h1>Hello JSX!</h1> |
创建一个复杂的 JSX 元素
JSX 也可以表示更复杂的 HTML。
关于嵌套的 JSX,需要知道的一件重要的事情,那就是它必须返回单个元素。
父元素将包裹所有其他级别的嵌套元素。
例如,几个作为兄弟元素而编写的JSX元素没有父元素包裹将不会被转换
1 | <!--有效的JSX--> |
在 JSX 中添加注释
使用{/* */}
语法来包裹注释文本
1 | const JSX = ( |
渲染 HTML 元素为 DOM 树
渲染 API(ReactDOM)将此 JSX 直接渲染到 HTML DOM。
ReactDOM 提供了一个简单的方法来将 React 元素呈现给 DOM,如下所示:ReactDOM.render(componentToRender, targetNode)
,其中第一个参数是要渲染的 React 元素或组件,第二个参数是要将组件渲染到的 DOM 节点。
1 | const JSX = ( |
在 JSX 中定义一个 HTML Class
到目前为止,HTML 和 JSX 似乎完全相同。
JSX 的一个关键区别是你不能再使用class
这个单词来定义 HTML 的 class 名。这是因为class
是 JavaScript 中的关键字。JSX 使用className
代替。
事实上,JSX 中所有 HTML 属性和事件引用的命名约定都变成了驼峰式。例如,JSX 中的单击事件是 onClick
,而不是 onclick
。同样,onchange
变成了onChange
。虽然这是一个微妙的差异,但一定要记住。
1 | const JSX = ( |
了解自动闭合的 JSX 标记
JSX 不同于 HTML 的另一个重要方面是自闭合标签在 JSX 中,规则略有不同。任何 JSX 元素都可以使用自闭合标签编写,并且每个元素都必须关闭。例如,换行标签必须始终编写为<br />
。另一方面<div>
可以写成<div />
或者<div></div>
。不同之处在于,在第一个语法版本中,无法在<div />
中包含任何内容。
创建一个无状态的函数组件
使用 JavaScript 函数创建React组件,以这种方式定义组件会创建无状态功能组件。
无状态组件视为可以接收数据并对其进行渲染的组件,但是它不管理或跟踪对数据的更改.
要用函数创建组件,只需编写一个返回 JSX 或null
的 JavaScript 函数。需要注意的一点是,React 要求你的函数名以大写字母开头。下面是一个无状态功能组件的示例,该组件在 JSX 中分配一个 HTML 的 class:
1 | const DemoComponent = function() { |
创建一个 React 组件
定义 React 组件的另一种方法是使用 ES6 的class
语法。在以下示例中,Kitten
扩展了React.Component
:
1 | class Kitten extends React.Component { |
用组合的方式创建一个 React 组件
创建了三个组件:Navbar
、Dashboard
和Footer
。创建一个App
父组件,将这三个组件分别渲染成为子组件,在render
方法中,你可以这样编写:
1 | return ( |
当 React 遇到引用另一个组件的自定义 HTML 标签时(如本例所示,组件名称包含在< />
中),它在标签的位置渲染该组件的标签。这可以说明App
组件和Navbar
、Dashboard
以及Footer
之间的父子关系。
渲染 class 组件为 Dom 树
如果不调用 ReactDOM API,你编写的任何 React 代码都不会渲染到 DOM。
ReactDOM.render(componentToRender, targetNode)
。第一个参数是要渲染的 React 组件。第二个参数是要在其中渲染该组件的 DOM 节点
React 组件传递到ReactDOM.render()
与 JSX 元素略有不同。对于 JSX 元素,你传入的是要渲染的元素的名称。但是,对于 React 组件,你需要使用与渲染嵌套组件相同的语法:
ReactDOM.render(<ComponentToRender />, targetNode)
。
写一个 React 组件
1 | class MyComponent extends React.Component{ |
将 Props 传递给无状态函数组件
现在是时候看看 React 中的另一个常见特性 props 了。在 React 中,你可以将属性传递给子组件。假设你有一个App
组件,该组件渲染了一个名为Welcome
的子组件,它是一个无状态函数组件。可以通过以下方式给Welcome
传递一个user
属性:
1 | <App> |
使用自定义 HTML 属性,React 支持将属性user
传递给组件Welcome
。由于Welcome
是一个无状态函数组件,它可以像这样访问该值:
1 | const Welcome = (props) => <h1>Hello, {props.user}!</h1> |
调用props
这个值是常见做法,当处理无状态函数组件时,基本上可以将其视为返回 JSX 的函数的参数。这样,就可以在函数体中访问该值。但对于类组件,访问方式会略有不同。
传递一个数组作为 Props
要将数组传递给 JSX 元素,必须将其视为 JavaScript 并用花括号括起来。
1 | <ParentComponent> |
这样,子组件就可以访问数组属性colors
。访问属性时可以使用join()
等数组方法。
1 | const ChildComponent = (props) => <p>{props.colors.join(', ')}</p> |
使用默认的 Props
React 还有一个设置默认 props 的选项。将默认 props 作为组件本身的属性分配给组件,React 会在必要时分配默认 prop。例如,如果你声明MyComponent.defaultProps = { location: 'San Francisco' }
,即定义一个 location 属性,并且其值在没有另行制定的情况下被设置为字符串San Francisco
。如果 props 未定义,则 React 会分配默认 props,但如果你将null
作为 prop 的值,它将保持null
。
覆盖默认的 Props
1 | const Items = (props) => { |
使用 PropTypes 来定义你期望的 Props
你可以在组件上设置propTypes
,以要求数据的类型为array
。当数据是任何其他类型时,都会抛出警告。当你提前知道 prop 的类型时,最好的做法是设置propTypes
。可以为组件定义propTypes
属性,方法与定义defaultProps
相同。这样做将检查给定键的 prop 是否是给定类型。这里有一个示例,名为handleClick
的 prop 应为function
类型:
1 | MyComponent.propTypes = { handleClick: PropTypes.func.isRequired } |
PropTypes.func
部分检查handleClick
是否为函数。添加isRequired
是为了告诉 ReacthandleClick
是该组件的必需属性。如果未提供该 prop,你将看到警告信息。另请注意,func
表示function
。在 7 种 JavaScript 基本类型中,function
和boolean
(写为bool
)是仅有的使用异常拼写的两种类型。除了基本类型,还有其他类型可用
PropTypes
可以从 React 中单独引入,如下所示:
1 | import React, { PropTypes } from 'react'; |
使用 this.props 访问 Props
倘若接收 prop 的子组件不是无状态函数组件,而是一个 ES6 类组件又当如何呢?ES6 类组件访问 props 的方法略有不同。
任何时候,只要引用类组件本身,就要使用this
关键字。要访问类组件中的 props,需要在在访问它的代码前面添加this
。例如,如果 ES6 类组件有一个名为data
的 prop,可以在 JSX 中这样写:{this.props.data}
。
使用 Props 和无状态函数组件
1 | class CampSite extends React.Component { |