Предназначен ли Portal API React 16 для замены API контекста?

Я заметил новую особенность portals сделать то же самое, но лучше? Я не очень разбираюсь в порталах, но, похоже, это новый способ управления обновлениями вложенных компонентов? Я знал, что Reacts Context API был экспериментальным, и заметил, componentDidUpdate больше не получает prevContext и они упали contextTypes,

Я также заметил, что они представляют Real 16 Portal API и не уверен, что он предназначен для замены Context API.

Итак, еще раз, как упомянуто выше, предназначен ли Portal API React 16 для замены Context API?

РЕДАКТИРОВАТЬ: В дополнение к этой теме, является ли conext лучшим способом управления локализацией i18n в реагировать?

2 ответа

Решение

TL; DR => Portals а также Context решать разные задачи, одна - вводить DOM на любом уровне, а другая - вводить реквизит на любом уровне. Context может подражать Portals но Portals КАК СЕЙЧАС не может подражать Context по крайней мере, без введения запаха кода.

ПРИМЕЧАНИЕ: ниже, основано на моем понимании этих двух понятий, если у кого-то есть дальнейшие мысли или исправления по этому поводу, пожалуйста, не стесняйтесь редактировать ответ.

Из того, что я смог понять Portals как следует из названия, это удобный способ визуализации компонентов, которые не обязательно должны находиться в иерархии дерева компонентов. Это работает как идеально для Modals, Popovers или любой компонент, который должен быть сшит в определенном месте дерева.

Context заключается в том, чтобы общаться с различными одноуровневыми и дочерними компонентами без необходимости передавать реквизиты от родительского к намеченному компоненту. Конечно, это важная особенность, но она осталась на экспериментальной стадии, вероятно, из-за того, что это может быть достигнуто event-emitters а также Redux, MobX для централизованного государственного управления.

Я предполагаю, что ваш вариант использования для i18n потребует много общения между компонентами, которые вы могли бы посмотреть на эту замечательную статью

КОМПОНЕНТНАЯ СВЯЗЬ

Порталы и Контекст помогают достичь такого рода коммуникации, но есть разница. Порталы могут визуализировать или внедрять DOM на любом уровне, а Context может внедрять реквизиты на любом уровне в дереве подкомпонентов.

Вы всегда можете достичь того, что Portals умеют делать с помощью Context но я не думаю Portals может подражать Context функциональность.

ЭГ: Нечто подобное можно сделать, чтобы имитировать то, что 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, что представляет собой риск, который может пойти обоими путями.

ВЫВОД: ИМО, Portals в его текущем состоянии и проблема, которую он пытается решить, полностью отличается от того, что Context построен и лучше использовать event-emitters с единственной причиной, по которой Context возможно, не рекомендуется.

API портала отличается от API контекста,

Portals обеспечить первоклассный способ визуализации дочерних элементов в узле DOM, который существует вне иерархии DOM родительского компонента.

Портал полезен, когда вы можете визуализировать модалы или всплывающие окна, которые должны находиться за пределами текущей иерархии DOM, чтобы иметь надлежащие z-индексы. Чаще всего вы делаете это на верхнем уровне напрямую. Однако с Portal вы можете визуализировать элемент DOM на любом уровне иерархии.

В React 16 Порталы могут быть созданы как

ReactDOM.createPortal(child, container)

Context с другой стороны, используется для передачи данных на другой компонент без необходимости их передачи на каждом уровне. У вас могут быть компоненты на различном уровне, некоторые из которых могут быть чрезвычайно вложенными, и передача реквизита вниз на каждом уровне может быть не лучшим решением, и это сопряжено со значительными помехами производительности, поскольку во многих случаях более высокие уровни на самом деле не могут быть используя эти реквизиты, но по-прежнему будет повторять рендеринг с такими изменениями реквизита.

С версии 16.3.0 React представила новый context API и контекст больше не является экспериментальным.

Контекст предназначен для совместного использования данных, которые можно считать "глобальными" для дерева компонентов 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?>
   }
}

и для компонента, который вы хотите использовать значение контекста, вы должны написать

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

Другие вопросы по тегам