簡體   English   中英

React 16的Portal API是否意味着要取代Context API?

[英]Is React 16's Portal API meant to replace the Context API?

我注意到新功能portals做同樣的事情,但更好? 我不太了解門戶網站,但它似乎是管理嵌套組件更新的新方法? 我知道Reacts Context API是實驗性的,並且注意到componentDidUpdate不再接收prevContext並且他們刪除了contextTypes

我還注意到他們正在引入React 16的Portal API,並且不確定它是否打算替換Context API。

那么,如上所述,React 16的Portal API是否意味着要取代Context API?

編輯:為了捎帶這個話題,conext是管理i18n本地化的最佳方式嗎?

TL; DR => PortalsContext解決不同的目的,一個是在任何級別注入DOM,另一個是在任何級別注入道具。 Context可以模仿Portals但是現在的Portals不能模仿Context ,至少在沒有引入代碼嗅覺的情況下。

注意:以下是基於我對這兩個概念的理解,如果有人對此有進一步的想法或更正,請隨時編輯答案。

從我能夠理解的東西,正如其名稱所示, Portals可以為您呈現不必在組件樹層次結構中的組件。 這對於ModalsPopovers或任何需要在樹中的特定位置縫合的組件來說非常有效。

Context是與各種兄弟和子組件進行通信,而不必將props從父級一直傳遞到目標組件。 當然,這是一個重要的特性,但它仍然處於實驗階段,這可能是由於event-emittersReduxMobX可以實現集中式狀態管理。

我假設您的i18n用例需要在組件之間進行大量通信,您可能需要查看這篇文章

組件通信

在此輸入圖像描述

門戶和上下文有助於實現這種通信,但存在差異。 門戶可以在任何級別渲染或注入DOM,Context可以在子組件樹中的任何級別注入道具。

您總是可以使用Context實現Portals能夠實現的功能,但我不認為Portals可以模仿Context功能。

EG:這樣的事情可以模仿Portals使用Context做什么。 Portals AFAIK中,您只能發送DOM節點ReactDOM.createPortal(child, container) 可能有一種方法來實現功能,但肯定會導致代碼味道。

class Parent extends React.Component {

    getChildContext() {
        return {
            renderModal: this.renderModal
        }
    }

    renderModal = (children) => {
        this.setState({
            open: !this.state.open,
            injectableChildren: children
        })
    }

    render() {
        this.state.open
            ?
            <div>
                {this.state.injectableChildren}
            </div>
            : 
            null
        // JSX
    }
}


class SomeSibling extends React.Component {
    static contextTypes = {
       renderModal: React.PropTypes.func
    }

    handleOnClick = (event) => {
        this.context.renderModal(renderableChildJSX);
    }

    renderableChildJSX = () => (
        <div>
            YAY I AM GETTING RENDERED AT THE ROOT
        </div>
    )

    render() {
        return(
            <div onClick={this.handleOnClick}>
            </div>
        )
    }
}

在我的情況下,我擔心使用Context盡管它具有靈活性,因為React文檔總是提到它是一個實驗性功能並且反復警告使用這個功能全面。 我的猜測是,React正在考慮穩定此功能,或者完全將其從React代碼庫中刪除,這可能是雙向的。

結論: IMO, Portals處於當前狀態,它試圖解決的問題與構建Context的問題完全不同,最好使用event-emitters ,唯一的原因是Context可能會被棄用。

Portal API與Context API不同,

Portals提供了一種將子項呈現為存在於父組件的DOM層次結構之外的DOM節點的第一類方法。

當您可能想要渲染模式或彈出窗口時,門戶網站非常有用,它需要在當前DOM層次結構之外才能使其具有正確的z索引。 大多數情況下,您會直接在頂層渲染這些。 但是使用Portal,您可以在任何層次結構中呈現DOM元素。

React 16 ,可以創建類似的門戶

ReactDOM.createPortal(child, container)

另一方面, Context用於將數據傳遞到不同的組件,而不需要在每個級別向下傳遞。 您可能擁有不同級別的組件,其中一些可能是非常嵌套的,並且在每個級別上將道具一直向下傳遞可能不是一個很好的解決方案,並且它具有顯着的性能障礙,因為很多較高級別可能實際上不是使用這些道具但仍然會在這樣的道具變化上重新渲染。

從v16.3.0開始,React引入了一個新的context API ,上下文不再是實驗性的。

Context旨在共享可被視為React組件樹的“全局”數據,例如當前經過身份驗證的用戶,主題或首選語言。 使用上下文,我們可以避免通過中間元素傳遞道具。 但它不應該只用於將道具傳遞幾級

一般來說,你會使用像上下文

export const MyContext = React.createContext();

class Provider extends React.Component {
   state = {
       theme: 'dark'
   }
   handleChange=() => {}

   render() {
        return <MyContext.Provider 
           value={{state: this.state, handleChange: this.handleChange}}
           >
               {this.props.children}
           </MyContext.Provider?>
   }
}

對於要使用上下文值的Component,您可以編寫

import {MyContext} from 'path/to/context'
...
render() {
    return <MyContext.Consumer>
         {(theme) => <div>{theme}</div>}
     </MyContext.Consumer>
}

回顧這個主題,上下文是管理i18n本地化的最佳方式嗎?

是的i18n本地化是使用上下文的一個很好的用例,因為您需要在整個應用程序中傳遞語言/分類選擇。 如果您需要與API進行更多集成來進行本地化,您可以考慮使用Redux。

有關更多詳細信息,請查看whether to use Context or Redux答案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM