<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] React 16版本有一個名為 Fiber 的新核心架構。 # 事件機制 # setState # `React.lazy` 與 `React.Suspense` > `React.lazy`和 Suspense 技術還不支持服務端渲染。如果你想要在使用服務端渲染的應用中使用,我們推薦[Loadable Components](https://github.com/gregberge/loadable-components)這個庫。它有一個很棒的[服務端渲染打包指南](https://loadable-components.com/docs/server-side-rendering/)。 > `React.lazy`目前只支持默認導出(default exports) `React.Suspense`也是一種虛擬組件(類似于[Fragment](https://reactjs.org/docs/react-api.html#reactfragment),僅用作類型標識),用法如下: ``` import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom'; import React, { Suspense, lazy } from 'react'; const Home = lazy(() => import('./Home')); const Bar = lazy(() => import('./Bar')); const App = () => ( <Router> <Suspense fallback={<div>loading</div>}> <div> <ul> <li><Link to="/">Home></Link></li> <li><Link to="/bar">Bar></Link></li> </ul> </div> <Switch> <Route exact path="/" component={Home} /> <Route path="/bar" component={Bar} /> </Switch> </Suspense> </Router> ) export default App; ``` `Suspense`子樹中只要存在還沒回來的 Lazy 組件,就走`fallback`指定的內容。**這不正是可以提升到任意祖先級的loading嗎?** http://www.ayqy.net/blog/react-suspense/ # React Context React的 context 就是一個全局變量,可以從根組件跨級別在 React 的組件中傳遞。React context 的API有兩個版本,React16.x 之前的是 老版本的 context,之后的是新版本的 context。 新版本的 React context 使用了`Provider`和`Customer`模式,和 react-redux 的模式非常像。在頂層的`Provider`中傳入`value`, 在子孫級的`Consumer`中獲取該值,并且能夠傳遞函數,用來修改 context,如下代碼所示: ``` import React, { createContext } from 'react'; // 創建Context的唯一方法 const ThemeContext = createContext() const SizeContext = createContext() class App extends React.Component { state = { theme: 'red', size: 'small' } render () { const { theme, size } = this.state return ( // 使用 Context.Provider 包裹后續組件,value 指定值 <ThemeContext.Provider value={theme}> {/* 當出現多個Context的時候,只需要將Context.Provider 嵌套即可 */} <SizeContext.Provider value={size}> {/* 當Context的Provider值更改時,Consumer 的值必須重新渲染 */} <button onClick={() => {this.setState({ theme: 'yellow', size: 'big'})}}>按鈕</button> <Middle></Middle> </SizeContext.Provider> </ThemeContext.Provider> ) } } class Bottom extends React.Component { render () { return ( // Context.Consumer Consumer 消費者使用 Context 得值 // 但子組件不能是其他組件,必須渲染一個函數,函數的參數就是 Context 得值 // 當出現 多個 Consumer 的時候,進行嵌套,每個 Consumer 的子組件必須是一個函數,即可 <ThemeContext.Consumer> { theme => ( <SizeContext.Consumer> { size => (<h1>ThemeContext 的 值為 {theme}; SizeContext 的值為 {size}</h1>) } </SizeContext.Consumer> ) } </ThemeContext.Consumer> ) } } class Middle extends React.Component { render () { return <Bottom></Bottom> } } export default App; ``` * 當 Provider 提供的值更改時,Consumer 必須重新渲染 * context 不僅僅只是可以傳數值,也可以傳函數。 * 創建 Context 的時候`createContext`可以傳入默認值,當向上找不到 Provider 的時候,就會顯示默認值 > 注意:context 類似于全局變量做法,會讓組件失去獨立性、復用起來更困難,不能濫用、但本身它一定有適合使用的場景,具體看情況使用 ## contextType React 16.6 引入了在不直接使用 Consumer 組件的情況下從上下文消費數據的功能。這有助于減少組件 JSX 中不必要的嵌套,使它們更易于閱讀。 ``` import React, { createContext } from 'react'; // 創建Context的唯一方法 const ThemeContext = createContext() const SizeContext = createContext() class App extends React.Component { state = { theme: 'red', size: 'small' } render () { const { theme, size } = this.state return ( // 使用 Context.Provider 包裹后續組件,value 指定值 <ThemeContext.Provider value={theme}> {/* 當出現多個Context的時候,只需要將Context.Provider 嵌套即可 */} <SizeContext.Provider value={size}> {/* 當Context的Provider值更改時,Consumer 的值必須重新渲染 */} <button onClick={() => {this.setState({ theme: 'yellow', size: 'big'})}}>按鈕</button> <Middle></Middle> </SizeContext.Provider> </ThemeContext.Provider> ) } } class Bottom extends React.Component { // 申明靜態變量、contextType 將 context 直接賦值于 contextType static contextType = ThemeContext render () { // 在 render 函數中 可以直接 訪問 this.context 獲取共享變量、這樣就可以不使用 consumer const theme = this.context return ( // Context.Consumer Consumer消費者使用Context得值 // 但子組件不能是其他組件,必須渲染一個函數,函數的參數就是Context得值 // 當出現 多個Consumer的時候,進行嵌套,每個Consumer 的子組件必須是一個函數,即可 <div> <h1>ThemeContext 的 值為 {theme} </h1> </div> ) } } class Middle extends React.Component { render () { return <Bottom></Bottom> } } export default App; ``` * `contextType`只能在類組件中使用 * 一個組件如果有多個consumer, contextType 只對其中一個有效,所以說,`contextType`只能有一個 ## React context的局限性 1. 在組件樹中,如果中間某一個組件 `ShouldComponentUpdate` `returning false` 了,會阻礙 context 的正常傳值,導致子組件無法獲取更新。 2. 組件本身 extends `React.PureComponent` 也會阻礙 context 的更新。 注意點: 1. Context 應該是唯一不可變的 2. 組件只在初始化的時候去獲取 Context > [context.html#classcontexttype](https://reactjs.org/docs/context.html#classcontexttype) > [React context基本用法](https://www.cnblogs.com/mengff/p/9511419.html) # 新的生命周期 需要關注新的[聲明周期](https://zh-hans.reactjs.org/docs/react-component.html): ![](https://img.kancloud.cn/a5/04/a504a443428b20eadc2778941ad1779c_904x617.png) 目前在 16.4 版本中: * ~~componentWillMount~~, * ~~componentWillReceiveProps~~, * ~~componentWillUpdate~~ 并未完全刪除這三個生命周期函數,而且新增了 * `UNSAFE_componentWillMount`, * `UNSAFE_componentWillReceiveProps`, * `UNSAFE_componentWillUpdate` 三個函數,官方計劃在 17 版本完全刪除這三個函數,只保留 `UNSAVE_` 前綴的三個函數,目的是為了向下兼容,但是對于開發者而言應該盡量避免使用他們,而是使用新增的生命周期函數替代它們 **取而代之的生命周期** 1. [static getDerivedStateFromProps(nextProps, prevState)](https://zh-hans.reactjs.org/docs/react-component.html#static-getderivedstatefromprops) 2. [getSnapshotBeforeUpdate(prevProps, prevState)](https://zh-hans.reactjs.org/docs/react-component.html#getsnapshotbeforeupdate) ## `getDerivedStateFromProps` 當我們接收到新的`props`,想去修改我們state,可以使用`getDerivedStateFromProps`。 ``` class ExampleComponent extends React.Component { state = { isScrollingDown: false, lastRow: null } static getDerivedStateFromProps(nextProps,prevState){ if(nextProps.currentRow !== prevState.lastRow){ return { isScrollingDown: nextProps.currentRow &gt; prevState.lastRow, lastRow: nextProps.currentRow } } return null; } } ``` ## `getSnapshotBeforeUpdate` 這個函數有一個返回值,會作為第三個參數傳給 `componentDidUpdate`,如果你不想要返回值,請返回 `null`,不寫的話控制臺會有警告 ``` class ScrollingList extends React.Component { constructor(props) { super(props); this.listRef = React.createRef(); } getSnapshotBeforeUpdate(prevProps, prevState) { //表示之前的props 和之前的 state // Are we adding new items to the list? // Capture the scroll position so we can adjust scroll later. if (prevProps.list.length < this.props.list.length) { const list = this.listRef.current; return list.scrollHeight - list.scrollTop; } return null; } componentDidUpdate(prevProps, prevState, snapshot) { // If we have a snapshot value, we've just added new items. // Adjust scroll so these new items don't push the old ones out of view. // (snapshot here is the value returned from getSnapshotBeforeUpdate) if (snapshot !== null) { const list = this.listRef.current; list.scrollTop = list.scrollHeight - snapshot; } } render() { return ( <div ref={this.listRef}>{/* ...contents... */}</div> ); } } ``` ## `componentDidUpdate(prevProps, prevState, snapshot)` 該方法在`getSnapshotBeforeUpdate`方法之后被調用,有三個參數`prevProps,prevState,snapshot`,**表示之前的props,之前的state,和snapshot**。第三個參數是`getSnapshotBeforeUpdate`返回的。 ## 參考 [生命周期圖](http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/) [官網 - 組件的生命周期](https://zh-hans.reactjs.org/docs/react-component.html#the-component-lifecycle) [[譯]如何使用React生命周期方法](https://juejin.im/post/5b59d1c8e51d4519455846e0) [React 16.6.X版本的更新功能](https://www.jianshu.com/p/406bcc058790) [盤點 React 16.0 ~ 16.5 主要更新及其應用](https://www.cnblogs.com/sunshq/p/10430728.html)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看