logo
  • 現在做什麼
  • 關於我

Kalan

文章分類

  • 前端
  • 開發筆記
  • 雜談
  • 年度回顧

快速連結

  • 現在做什麼
  • 關於我
  • 聯絡我
  • 職涯思考🔗

關注我

在福岡生活的開發者,分享軟體開發與日本生活的點點滴滴。

© 2025 Kalan Made with ❤️. All rights reserved.

React16 重點整理

由愷開愷開撰寫2017年10月2日 9:00
首頁/前端
💡

如果想問問題或單純回饋的話可以填寫表單唷

English日文

目錄

  1. 1. componentDidPatch(error, info)
  2. 2. Text-Only component
  3. *3. ReactDOM.createPortal(component, dom)
  4. 4. Custom Attributes
  5. 5. prevent update
  6. 6. SSR 的支援
  7. 結論

react 終於正式發佈 v16 了,其實官方部落格的介紹已經相當完整(而且賞心悅目)。本篇文章作為筆記與統整,精簡了部分的細節。

1. componentDidPatch(error, info)

react16 最亮眼的部分,加入 ErrorBoundary 的功能,確保在 lifecycle 時的錯誤不會影響到整個 component。之前如果在 render 時發生錯誤,會導致整個 component 不見。

只有在 Error 在 lifecycle method 被呼叫時才會傳入 componentDidPatch,所以在 constructor 之類的地方 throw Error 是不會被 componentDidCatch 給 catch 的。

componentDidCatch 傳入兩個參數 error, info。可以在 componentDidCatch 內處理錯誤,fallback UI 或是呼叫第三方服務紀錄錯誤等等。

class Post extends Component {
  constructor() {
    throw new Error("oops") // 不會傳入 componentDidCatch
  }

  componentWillMount() {
    this.setState(state => {
      throw new Error("oops")
      return {}
    })
  }
}
class App extends Component {
  constructor() {
    super(props)
    this.state = {
      post: { content: "" },
    }
  }

  updatePost = () => {
    this.setState(state => ({ ...state, post: null }))
  }

  componentDidCatch(error, info) {
    this.setState({ hasError: true })
    Logger.warn(error, info)
  }

  render() {
    return (
      <div>
        <Post post={this.state.post} />
      </div>
    )
  }
}

除了上面的範例之外,你也可以透過 higher order component 的技巧將 componentDidCatch 包裝,或者是設定 ErrorBoundary 等等的 component 統一處理 children 的錯誤。

2. Text-Only component

刪除了不必要的 span 與 react-text 節點,並且可以直接回傳字串。

const Text = ({ text }) => {
  return "pure string!"
}
class App extends Component {
  render() {
    return (
      <div>
        <Text /> // render 'pure string', rather than <span>pure string</span>
      </div>
    )
  }
}

*3. ReactDOM.createPortal(component, dom)

createPortal 也是我相當喜歡的新功能之一,他能夠透過在 Component Tree 裡頭另外 render 到其他 DOM 上,並且可以完全脫離 Children 也沒有關係,像是下面的結構。

<div id="app1"></div>
<div id="app2"></div>
class App extends Component {
  constructor() {}

  render() {
    ;<div>
      <h2>Main header</h2>
      {ReactDOM.createPortal(<Sidebar />, document.querySelector("#app2"))}
    </div>
  }
}

App 裡頭可以透過 ReactDOM.createPortal(),除了閱讀性比較好之外(不用透過 callback 或是直接操作 DOM 的方式),還能夠對 Children 以外的節點操作,對於寫像是 modal 這種可能需要 overlay 的 component 很方便。(overlay 可能要再根節點上,比較好處理)

4. Custom Attributes

render() {
  return (
  	<div ui-prefix-scroller='foo'>
    </div>
  )
};

5. prevent update

在 setState 回傳 null 不會觸發更新(之前的版本會)。以後不想更新 component 可以透過傳入 null 來解決。

6. SSR 的支援

詳細可以參考 What's new with serverside rendering in react16,值得一提的是 react16 SSR 開始支援 stream,renderToNodeStream(Component) 回傳 stream。

以及文章作者提到的:

please, please, please make sure you always set NODE_ENV to production when using React SSR in production!

結論

以上就是 React 16 的主要更動。官方部落格有更詳盡的介紹。

← 2017 年前端面試心得Better Express error →

如果覺得這篇文章對你有幫助的話,可以考慮下面的連結請我喝一杯 ☕ 可以讓我平凡的一天變得閃閃發光 ✨

☕Buy me a coffee

目錄

  1. 1. componentDidPatch(error, info)
  2. 2. Text-Only component
  3. *3. ReactDOM.createPortal(component, dom)
  4. 4. Custom Attributes
  5. 5. prevent update
  6. 6. SSR 的支援
  7. 結論