從16年夏天初學React,到17年正式投入到工做中使用,直到如今V16.2發版,React發生了巨大的變化,最近在工做中使用時遇到不少基礎不是很是清晰,藉此再讀 React官方文檔 【中文】。
React核心的單向數據流、一切皆數據的state、不會改變的props,以及狀態提高等等常用便很少總結,須要的看官方文檔。html
JSX 本質只是爲 React.createElement(component, props, ...children)提供的語法糖!react
如下兩段代碼等價(許多react的界面設計器經過這個原理,達到元數據轉化React元素,實現界面化編程!)
嵌套就是多個create方法的嵌套。express
function hello() { return <div className="red">Hello,<span>world!</span></div>; }
"use strict"; function hello() { return React.createElement( "div", { className: "red" }, "Hello,", React.createElement( "span", null, "world!" ) ); }
須要循環和條件渲染可使用map、三目,或者使用if/for在jsx代碼以外!編程
//錯誤的! class A extends React.Component { render() { return <div>{if(){}else{}}</div>;//原來還矇蔽的不知道爲何錯了0.0 } }
建立組件的四種方式:詳情對比參見或者react官網數組
class Greeting extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } }
var createReactClass = require('create-react-class'); var Greeting = createReactClass({ render: function() { return <h1>Hello, {this.props.name}</h1>; } }); //或者使用react var Greeting = React.create({ render: function() { return <h1>Hello, {this.props.name}</h1>; } });
const Button = ({ day, increment }) => { return ( <div> <button onClick={increment}>Today is {day}</button> </div> ) }
大多數狀況下, 咱們使用PureComponent可以簡化咱們的代碼,而且提升性能,可是PureComponent的自動爲咱們添加的shouldComponentUpate函數,只是對props和state進行淺比較(shadow comparison),當props或者state自己是嵌套對象或數組等時,淺比較並不能獲得預期的結果,這會致使實際的props和state發生了變化,但組件卻沒有更新的問題。固然仍是有解決的方法的,因此建議仍是少用。babel
事件綁定的四種方法:推薦使用第一第二種。dom
class Toggle extends React.Component { constructor(props) { {...} //方法一必須在這裏綁定 this.handleClick1 = this.handleClick.bind(this); } handleClick1() { this... } //方法二使用【屬性初始化器語法】【須要開啓babel stage-0以上】 handleClick2=()=> { this... } render() { return ( <div> <button onClick={this.handleClick1}></button> <button onClick={this.handleClick2}></button> //方法三在使用時綁定 <button onClick={this.handleClick1.bind(this)}></button> //方法四在回調函數中使用 箭頭函數 /** 渲染的時候都會建立一個不一樣的回調函數。在大多數狀況下,這沒有問題。然而若是這個回調函數做爲一個屬性值傳入低階組件,這些組件可能會進行額外的從新渲染。咱們一般建議在構造函數中綁定或使用屬性初始化器語法來避免這類性能問題。 **/ <button onClick={(e) => this.handleClick1(e)}></button> </div> ); } }
在React中不推薦使用繼承,不推薦繼承自定義Component。函數
//不推薦使用 class Parent extends React.Component { render() { return <div>...</div>; } } class A extends Parent { render() { return <div>...</div>; } }
//推薦使用 class A extends React.Component { render() { return <Parent>...</Parent>; } }
class Greeting extends React.Component { constructor(props) { super(props); this.state = {count: props.initialCount}; this.handleClick = this.handleClick.bind(this); } handleClick() { alert(this.state.message); } render() { return <h1 onClick={this.handleClick}>Hello, {this.props.name}</h1>; } } Greeting.defaultProps = { name: 'Mary' };
var createReactClass = require('create-react-class'); var Greeting = createReactClass({ getInitialState: function() { return {count: this.props.initialCount}; }, getDefaultProps: function() { return { name: 'Mary' }; }, handleClick: function() { alert(this.state.message); }, render: function() { //組件中的方法會自動綁定至實例,不須要像上面那樣加 .bind(this) return <h1 onClick={this.handleClick}>Hello, {this.props.name}</h1>; } });
function CustomTextInput(props) { return ( <div> <input ref={props.inputRef} /> </div> ); } class Parent extends React.Component { //this.inputElement 就是CustomTextInput中的input render() { return ( <CustomTextInput inputRef={el => this.inputElement = el} /> ); } }
獲取一個DOM除了refs還有更加簡單粗暴的方法findDOMNode
。
findDOMNode 是用於操做底層DOM節點的備用方案。使用它的優先級比refs更低!!
findDOMNode 只對掛載過的組件有效。
findDOMNode 不能用於函數式的組件中。性能
import ReactDOM from 'react-dom'; ReactDOM.render( element, container, [callback]//鮮爲人知的第三個參數!! ) ReactDOM.unmountComponentAtNode(container) ReactDOM.findDOMNode(component)
Fragments
<></>
或者<React.Fragment></React.Fragment>
&&
true && expression 老是返回 expression,而 false && expression 老是返回 false。null
組件的 render 方法返回 null 並不會影響該組件生命週期方法的回調。例如,componentWillUpdate 和 componentDidUpdate 依然能夠被調用。### 高階組件HOC 使用高階組件(HOC)解決交叉問題ui