React 文檔導讀 — 克服文檔中難懂卻有趣的用法吧!

本文站在初入React世界的新手,總結一些「不適應」或是有點「不明白」的文檔上範例,作為導讀,搭配官方文檔服用。

realdennis
6 min readMar 10, 2019

「用藥須知」

希望你是一個已經勇敢打開並看過文檔的人,而不是一開始就直接觀看別人總結的二手知識。作為導讀,目前依照v16.8.4的文檔順序,如果未來重大版本更新,請自行忽略舊有的API。

「用途」

作為一個優秀的開源UI函式庫,其文檔當然是相當優秀,中文的翻譯也是隨手 Google就能查到,這篇主要解釋新手會覺得「有點不適應」的部分。

「目錄」

  • 新手怎麼練習文檔上的用法?
  • JSX、HTML、React Element?
  • Class 組件傳 this 到底在 bind 什麼鬼?
  • setState 解構 state 物件到底在…?
  • 父子兄弟姐妹組件溝通不良?
Photo by Artem Sapegin on Unsplash

怎麼使用、練習 React?

Add React to a Website 文檔中提到幾個方法,比如使用CDN將 React 加入網頁中,並且透過在 ReactDOM.render 傳入根節點

// ... the starter code you pasted ...

const domContainer = document.querySelector('#like_button_container');
ReactDOM.render(e(LikeButton), domContainer);

這邊我先建議你不要這麼做,這樣寫起來會比你想象中的克難十多倍。

這邊建議使用官方提供的 CRA(Create-react-app)連結,官方準備的 boilerplate ,搭配的 React、ReactDOM 都會是最新且穩定的版本,而且已經幫你配置好了 Webpack。

你可以專注於練習React,而非花太多時間自己配置Webpack、Babel、JSX、Polyfill、打包然後放棄。

這裡推薦另外一個讓你更快開始寫React的地方 — CodeSandbox,選擇 React 專案後就可以在 Web 上直接撰寫 React App 。

在 JS 裡面寫HTML好酷喔!但我搞不清楚什麼時候是HTML?

React 使用名叫做 JSX 的東西,儘管你在 vscode 、 codesandbox ,看到程式碼裡頭有 html 並且依照標籤高亮…但它並不是真正的 HTML。

const FirstComp = ()=>{
return <p className="greeting"> Hello! </p>
}
(↑ 這是你在編寫程式碼時看到的)

(記得 class 要改成 className 、for 改成 htmlFor…思考一下為什麼吧!)

const FirstComp = ()=>{
return {
type:'p',
{ className:'greeting' },
'Hello!
}
}
(↑ 經過Webpack的babel轉譯之後)

所以你寫的那坨看似 HTML 的東西,其實是仰賴於許多人的努力喲!

  • babel — 針對像是HTML的東西拿去解析並且轉譯成這個樣子
  • React — 把這坨物件最終給渲染成真實節點 (createElement)

(props在幹嘛…event在幹嘛…這些自己去看)

props 就是 property 嘛!可以想象成組件對外的接口。就像函數吃參數一樣,組件也要能夠有可以吃的東西嘛,就是props。

<Comp isGoodToDrink={20}/>// Comp.jsx
export (props)=>{
return <p> Drink = {props.isGoodToDrink} </p>
}

Class組件好難喔?為什麼常常 this 會報錯?為什麼傳setter給子組件要特別bind啊?

你有兩個選擇:

一、 搞懂 JavaScript 的 this 用法,搞懂在 Class 裡頭什麼時候是實例,箭頭函數、bind在幹嘛。

JavaScript 的 this 到底是什麼?不懂 this 正在綁定的對象,連框架都難以使用…

二、 完全放棄在 JavaScript 使用 this,所有會碰到 this 的狀況都避免掉,使用箭頭函數、使用函數組件。

使用 React-Hooks 管理你的函數組件裡頭的狀態。

setState 裡頭的解構

在第一次觀看React文檔時,對於setState的用法一定是各種懵逼,讓我們來看看最傳統的類組件 — Class Component。

有時候我們的類組件狀態是長這個樣子:

this.state = { 
title : 'I am title',
height:400,
width: 300,
blablabla: {
xxx:20,
....
}
}

這種時候你要更新 title 的時候…必須要用setState,而且不能影響到其他的狀態嘛!

你總不希望更新完 title 之後結果狀態變成這樣

this.state = {
title: 'I am change'
}

所以 React 在這裡給了一個很給力的做法,只更新你想更新的狀態:

const obj = { title:'I am change' }
this.setState( prevState => Object.assign({}, prevState, obj))
// obj 跟 prevState 一起被assign到空物件裡頭,產生一個新的物件

有時候你會看到像是這樣子的:

const obj  = {name:'title', value:'I am Change'}
this.setState(prev=>Object.assign({},prev,{
[obj.name] : obj.value
}))

用這個像是陣列的框框把變數框住,之後就會變成 key 了。

const obj  = {name:'title', value:'I am Change'}
Object.assign({},{ [obj.name] : obj.value })
// {title:'I am Change'}

更多詳細的物件、陣列解構請看這篇 —《 解構賦值 — 設計函數時的小技巧

欸幹,我發現子組件的值沒辦法丟上來欸?

在UI框架裡頭最常被問的就是這個問題,不管你是在Vue還是React都會碰到,單向資料流就是會有這個問題。

Ans. 請你把狀態拉伸到父組件,再把操作狀態、操作一堆狀態的函數丟下去。

記得!如果你用Class Component,要注意 this 。

我要傳父組件跟兒子的兒子的兒子溝通怎麼辦?

Ans. 幾個給你參考的答案

  1. 透過 Props 一路把操作狀態的函數向下傳遞,state定在最上面。
  2. 遇到這個狀況,代表你已經遇到狀態管理的問題,可以看看 Redux
  3. 透過 React 原生的 Context API 包覆 Provider 跨組件溝通

尾聲

這篇文章不是那種 React 原始碼深度解析的高深文,而是統整當初認為有點複雜以及現在認為應該早點明白的概念。

希望這篇文章有幫助到你。

--

--

No responses yet