Предназначен ли 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