react版本:16.13.1
-
React 會將以小寫字母開頭的組件視爲原生 DOM 標籤,所以自定義組件名稱規範是大寫字母開頭。
-
JSX 裏的 class 變成了 className
-
JSX 防止注入攻擊:React DOM 在渲染所有輸入內容之前,默認會進行轉義。所有的內容在渲染之前都被轉換成了字符串。這樣可以有效地防止 XSS(cross-site-scripting, 跨站腳本)攻擊。
-
React DOM 會將元素和它的子元素與它們之前的狀態進行比較,並只會進行必要的更新來使 DOM 達到預期的狀態。
-
組件無論是使用函數聲明還是通過 class 聲明,都決不能修改自身的 props,props是隻讀的,直接修改會報錯。React 組件都必須像純函數一樣保護它們的 props 不被更改
-
純函數定義:
函數不會嘗試更改入參,且多次調用下相同的入參始終返回相同的結果。它不依賴於程序執行期間函數外部任何狀態或數據的變化,必須只依賴於其輸入參數。 -
State 與 props 類似,但是 state 是私有的,並且完全受控於當前組件。
-
componentDidMount() 方法會在組件已經被渲染到 DOM 中後運行
-
關於 setState() 你應該瞭解三件事:
-不要直接修改 State
-State 的更新可能是異步的:
React 可能會把多個 setState() 調用合併成一個調用。因爲 this.props 和 this.state 可能會異步更新,所以你不要依賴他們的值來更新下一個狀態。
要解決這個問題,可以讓 setState() 接收一個函數而不是一個對象。// Wrong this.setState({ counter: this.state.counter + this.props.increment, }); // Correct this.setState((state, props) => ({ counter: state.counter + props.increment }));
-State 的更新會被合併:
當你調用 setState() 的時候,React 會把你提供的對象合併到當前的 state。這裏的合併是淺合併 -
在 React 中你不能通過返回 false 的方式阻止默認行爲。你必須顯式的使用 preventDefault:
function ActionLink() { function handleClick(e) { e.preventDefault(); console.log('The link was clicked.'); } return ( <a href="#" onClick={handleClick}> Click me </a> ); }
-
JSX 回調函數中的 this,在 JavaScript 中,class 的方法默認不會綁定 this。
//方法一:在構造函數中綁定(ES2015) constructor(props) { super(props); this.handleClick = this.handleClick.bind(this);//將對象原型上的handleClick綁定到對象實例上 } handleClick() {//對象原型上綁定handleClick } render() { return ( <button onClick={this.handleClick}></button> ); } //方法二:class 屬性(第三階段提案) handleClick = () => {//直接在對象實例上綁定 console.log('this is:', this); } render() { return ( <button onClick={this.handleClick}></button> ); } //方法三:在 Render 中使用箭頭函數 handleClick() { console.log('this is:', this); } render() { // 此語法確保 `handleClick` 內的 `this` 已被綁定。 return ( <button onClick={() => this.handleClick()}></button> ); } //方法四:在 Render 中的綁定 handleClick() { console.log('this is:', this); } render() { // 此語法確保 `handleClick` 內的 `this` 已被綁定。 return ( <button onClick={this.handleClick.bind(this)}></button> ); }
方法三問題在於每次渲染都會創建不同的回調函數,如果該回調函數作爲 prop 傳入子組件時,這些組件可能會進行額外的重新渲染。可能會帶來性能問題。
方法四在 render 方法中使用 Function.prototype.bind 會在每次組件渲染時創建一個新的函數,可能會影響性能。所以最好用方法一或者二。 -
向事件處理程序傳遞參數
//在這兩種情況下,React 的事件對象 e 會被作爲第二個參數傳遞。 <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button> <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
-
阻止組件渲染:可以讓 render 方法直接返回 null,而不進行任何渲染。
-
在組件的 render 方法中返回 null 並不會影響組件的生命週期。
-
使 React 的 state 成爲“唯一數據源”。渲染表單的 React 組件還控制着用戶輸入過程中表單發生的操作。被 React 以這種方式控制取值的表單輸入元素就叫做“受控組件”。
-
渲染列表:
元素的 key 只有放在就近的數組上下文中才有意義。const numbers = [1, 2, 3, 4, 5]; const listItems = numbers.map((number) => <li key={number.toString()}>{number}</li> ); ReactDOM.render( <ul>{listItems}</ul>, document.getElementById('root') );
-
如果列表項目的順序可能會變化,我們不建議使用索引來用作 key 值,因爲這樣做會導致性能變差,還可能引起組件狀態的問題。
-
key 會傳遞信息給 React ,但不會傳遞給你的組件。
//Post 組件可以讀出 props.id,但是不能讀出 props.key。 const content = posts.map((post) => <Post key={post.id} id={post.id} title={post.title} /> );
-
在 select 標籤中選擇多個選項:
<select multiple={true} value={['B', 'C']}>
-
ES6 計算屬性名稱的語法更新給定輸入名稱對應的 state 值:
this.setState({ [name]: value }); //等同 ES5: var partialState = {}; partialState[name] = value; this.setState(partialState);
-
在受控組件上指定 value 的 prop 會阻止用戶更改輸入。如果你指定了 value,但輸入仍可編輯,則可能是你意外地將value 設置爲 undefined 或 null。
//input輸入值不可被修改,1秒後可以被修改 ReactDOM.render(<input value="hi" />, mountNode); setTimeout(function() { ReactDOM.render(<input value={null} />, mountNode); }, 1000);
-
通常,多個組件需要反映相同的變化數據,這時我們建議將共享狀態提升到最近的共同父組件中去。
-
JSX 標籤中的所有內容都會作爲一個 children prop 傳遞給JSX 標籤。
function FancyBorder(props) { return ( <div> {props.children} </div> ); } 這使得別的組件可以通過 JSX 嵌套,將任意組件作爲子組件傳遞給它們。 function WelcomeDialog() { return ( <FancyBorder> <h1 className="Dialog-title"> Welcome </h1> </FancyBorder> ); } //也可以自行約定 function SplitPane(props) { return ( <div className="SplitPane"> <div className="SplitPane-left"> {props.left} </div> <div className="SplitPane-right"> {props.right} </div> </div> ); } function App() { return ( <SplitPane left={ <Contacts /> } right={ <Chat /> } /> ); }