博客原文css
9102 年了,若是你还不会 React,但愿本文能够帮你快速了解 React.js 的基础知识。html
使用 create-react-app 工具快速建立 React SPA。vue
# 建立项目 yarn create react-app my-app cd my-app # 开发模式下运行程序 yarn start
项目初始结构:node
my-app/ README.md node_modules/ package.json public/ # 项目使用的公共文件 index.html # 首页的模板文件 favicon.ico # 项目的图标 mainifest.json # 移动端配置文件 src/ # 源代码 App.css App.js App.test.js index.css index.js # 入口文件 logo.svg
// src/index.js 入口文件 import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; // 将根组件渲染到 id 为 root 的 dom 上 ReactDOM.render(<App />, document.getElementById('root'));
// src/app.js 根组件 import React, { Component } from 'react'; // 建立根组件 class App extends Component { constructor(props) { super(props); this.state = { msg: 'Hello React' } } render() { // JSX 语法 return ( <div className="App"> <h1>{ this.state.msg }</h1> </div> ); } } export default App;
最终这个根组件会在页面上显示出内容为 Hello React 的 h1 标题。react
上例中在写根组件时,render 函数中提到了 JSX,简单的看,就是一个能够在 js 中写 html,简化了经过 React.createElement
建立 Dom,Babel 会将 JSX 转译。git
JSX 中有如下几点须要注意:github
<>
会当作 html 解析 {}
会当作 js 解析;<Fragment>
,须要引入 import { Fragment } from 'react'
;开始写以前先明确一下一个 ToDoList 的需求:json
先写一个名为 Todo 的组件,而后在 App 根组件中调用便可。app
App.js 中调用 Todo 组件。frontend
import React, { Component } from 'react'; import Todo from './Todo' class App extends Component { render() { return ( <Todo></Todo> ); } } export default App;
调用自定义的组件时直接像原生 html 组件同样使用 <>
,区别是自定义组件须要以大写字母开头。
// Todo.js import React, { Component, Fragment } from 'react'; import TodoItem from './TodoItem'; class Todo extends Component { constructor(props) { super(props); this.state = { inputVal: '早起', list: ['吃早饭', '洗脸刷牙'] }; this.inputChange = this.inputChange.bind(this); this.addItem = this.addItem.bind(this); this.delItem = this.delItem.bind(this); } render() { return ( <Fragment> <div> <label htmlFor="todoIpt">todo: </label> <input id="todoIpt" ref={iptRef => this.iptRef = iptRef} value={this.state.inputVal} onChange={this.inputChange} /> <button onClick={this.addItem}>+</button> </div> <ul> { this.state.list.map((item, idx) => { return ( <TodoItem key={idx+item} idx={idx} content={item} delItem={this.delItem} /> ) }) } </ul> </Fragment> ); } inputChange() { this.setState({ inputVal: this.iptRef.value }) } addItem() { this.setState({ list: [...this.state.list, this.state.inputVal] }) } delItem(idx) { const list = this.state.list; list.splice(idx, 1); this.setState({ list }) } } export default Todo;
仍然引入 react 及 react.component 并使用 class 建立组件。
constructor 中经过 super 继承父组件传入的数据,经过 state 定义组件内部的数据。
render 函数中在 {} 中使用 js 给 html 动态绑定数据及事件,绑定的事件也定义在 class 中,须要经过 bind 修改 this 指向。
这里使用 ref 将输入框节点获取并保存在 this.iptRef
上,在 onchange 事件中修改其绑定的数据 inputVal。
修改数据时须要调用 setState 方法才能出发视图的更新。
ul 中直接使用 js 的 map 方法遍历 state.list
生成展现列表,列表中的每一项又单独抽出来做为一个新的子组件 TodoItem,并将子组件须要的数据 idx、content 及方法 delItem 传给他。
须要注意的时遍历生成的组件若是没有添加 key 属性则会报警告。
import React, { Component } from 'react'; import PropTypes from 'prop-types'; class TodoItem extends Component { constructor(props) { super(props); this.state = {}; this.handleItemClick = this.handleItemClick.bind(this); } render() { return ( <li onClick={this.handleItemClick}> {`${this.props.idx + 1}. ${this.props.content}`} </li> ); } handleItemClick() { this.props.delItem && this.props.delItem(this.props.idx); } } TodoItem.propTypes = { idx: PropTypes.number.isRequired, content: PropTypes.string.isRequired, delItem: PropTypes.func } export default TodoItem;
子组件直接经过 props 拿到父组件传递的数据包括方法。
子组件无法直接修改父组件传来的数据,所以须要调用父组件的方法来修改,好比这里的点击删除该项就是调用了父组件的 delItem 方法。
这里还引入了 prop-types
来帮助子组件进行传入数据的类型检查,还能够添加 isRequired 代表该数据是必需要传的,若是没有按照这个限制传给子组件数据则会有报错提示。
如今这个需求基本已经完成了。
react 的每一个组件都有一套生命周期函数,在组件开始渲染、更新到销毁的每一个时间点都会执行对应的生命周期函数。
上面这个连接能够看到各类函数的执行顺序,最经常使用的 componentDidMount 就相似于 vue 的 mounted。
其中比较特殊的是 shouldComponentUpdate,它能够在组件更新以前进行拦截,return true
时才会执行 render 函数。
前面的 ToDoList 程序中,若是在子组件的 render 函数中增长一条 console.log 就会发现输入框的值每次变化都会触发全部组件的渲染,所以这里可使用 shouldComponentUpdate 进行拦截。
TodoItem 组件中添加:
shouldComponentUpdate(nextProps, nextState) {nextProps, nextState); return nextProps.content !== this.props.content; }
代表只有当 content 更新时才执行下一步 render 函数。
到这基本上对 react 有了一个基本的了解了。