博客原文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 有了一個基本的瞭解了。