Closed kjj6198 closed 7 years ago
react 終於正式發佈 v16 了,其實官方部落格的介紹已經相當完整(而且賞心悅目)。本篇文章作為筆記與統整,精簡了部分的細節。
react16 最吸引我的功能,加入 ErrorBoundary 的功能,確保在 lifecycle 時的錯誤不會影響到整個 component。 跟 try catch 的效果很像,不過是專門給 React component 使用的。之前如果在 render 時發生錯誤,會導致整個 component 不見,現在你可以透過 componentDidCatch 的方式來處理。
Note: 不過只有在 Error 在 lifecycle method 被呼叫時才會傳入 componentDidPatch,所以在 constructor 之類的地方 throw Error 是不會被 componentDidCatch 給 catch 的。
componentDidCatch 傳入兩個參數 error, info。可以在 componentDidCatch 內處理錯誤,fallback UI 或是呼叫第三方服務紀錄錯誤等等。
componentDidCatch
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 的錯誤。
ErrorBoundary
刪除了不必要的 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> ) } }
createPortal 也是我相當喜歡的新功能之一,他能夠透過在 Component Tree 裡頭另外 render 到其他 DOM 上,並且可以完全脫離 Children 也沒有關係,像是下面的結構。
createPortal
<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 可能要再根節點上,比較好處理)
App
ReactDOM.createPortal()
render() { return ( <div ui-prefix-scroller='foo'> </div> ) };
在 setState 回傳 null 不會觸發更新(之前的版本會)。以後不想更新 component 可以透過傳入 null 來解決。
詳細可以參考 What's new with serverside rendering in react16,值得一提的是 react16 SSR 開始支援 stream,renderToNodeStream(Component) 回傳 stream。
renderToNodeStream(Component)
以及文章作者提到的:
please, please, please make sure you always set NODE_ENV to production when using React SSR in production!
NODE_ENV
production
以上就是 React 16 的主要更動。官方部落格有更詳盡的介紹。
react 終於正式發佈 v16 了,其實官方部落格的介紹已經相當完整(而且賞心悅目)。本篇文章作為筆記與統整,精簡了部分的細節。
*1. componentDidPatch(error, info)
react16 最吸引我的功能,加入 ErrorBoundary 的功能,確保在 lifecycle 時的錯誤不會影響到整個 component。 跟 try catch 的效果很像,不過是專門給 React component 使用的。之前如果在 render 時發生錯誤,會導致整個 component 不見,現在你可以透過 componentDidCatch 的方式來處理。
Note: 不過只有在 Error 在 lifecycle method 被呼叫時才會傳入 componentDidPatch,所以在 constructor 之類的地方 throw Error 是不會被 componentDidCatch 給 catch 的。
componentDidCatch
傳入兩個參數 error, info。可以在 componentDidCatch 內處理錯誤,fallback UI 或是呼叫第三方服務紀錄錯誤等等。除了上面的範例之外,你也可以透過 higher order component 的技巧將
componentDidCatch
包裝,或者是設定ErrorBoundary
等等的 component 統一處理 children 的錯誤。2. Text-Only component
刪除了不必要的 span 與 react-text 節點,並且可以直接回傳字串。
*3. ReactDOM.createPortal(component, dom)
createPortal
也是我相當喜歡的新功能之一,他能夠透過在 Component Tree 裡頭另外 render 到其他 DOM 上,並且可以完全脫離 Children 也沒有關係,像是下面的結構。App
裡頭可以透過ReactDOM.createPortal()
,除了閱讀性比較好之外(不用透過 callback 或是直接操作 DOM 的方式),還能夠對 Children 以外的節點操作,對於寫像是 modal 這種可能需要 overlay 的 component 很方便。(overlay 可能要再根節點上,比較好處理)4. Custom Attributes
5. prevent update
在 setState 回傳 null 不會觸發更新(之前的版本會)。以後不想更新 component 可以透過傳入 null 來解決。
6. SSR 的支援
詳細可以參考 What's new with serverside rendering in react16,值得一提的是 react16 SSR 開始支援 stream,
renderToNodeStream(Component)
回傳 stream。以及文章作者提到的:
結論
以上就是 React 16 的主要更動。官方部落格有更詳盡的介紹。