Оригинальный адрес:⚛️ Новый контекстный API React
автор:kentcdodds
это уже не实验性的 API
, и это больше соответствует工程化
концепция, теперь она сталаReact 一级棒的 API
.
⚠️ : Все могут пройтиnewsletterПолучайте мои последние новости, которые я обычно отправляю по электронной почте каждые две недели, и вы можете получать больше контента через свой почтовый ящик.
React
серединаcontext API
Я верю, что все это знают, может быть, как и все, когда вы видитеReact
Когда официальная документация такая, вы боитесь использовать ее напрямую.
Первый результат поиска показываетпочему контекст не рекомендуется, пусть все беспокоятся моментально, глава описывает это такcontext
из:
Если вы хотите сделать свое приложение более стабильным, не используйте его
context
, так как это экспериментальныйAPI
, в будущемReact
может меняться от версии к версии.
⚠️ Обратите внимание, что изменения здесь включают中断
,终止
,不再使用
значение.
Итак, зачем вообще использовать контекст?
Вы когда-нибудь пробовали в层级很深的组件
получено в最外层组件
изstate
боль, эта боль называетсяprop drilling
, который близок к коллапсу. Когда это произойдет, вам определенно не понравится использоватьprops
для передачи данных, потому что, если один из компонентов в середине изменится, стоимость будет геометрией :joy:.
На самом деле, вы можете сделать это с помощью обычногоJavaScript module
Чтобы избежать описанных выше проблем, храните данные вmodule
, это может быть реализовано где угодно访问/导入
, но при этом хотелось бы更新
громоздко (вы должны реализоватьevent
Запускается при обновлении данных, уведомляя пользователя об изменении данных), и,服务端渲染
правильноmodule
Также естьОказать влияние.
Поэтому что-то вродеreduxтакая ответственность状态管理
Сторонняя библиотека попала в поле зрения каждого. Это позволяет вамstore
Чтобы получить данные, все, что вам нужно сделать, это использовать<Provider />
Упакуйте его, затем волшебным образом вconnected
Получить нужные данные из компонента несложно.
Однако, если бы я сказал вам<Provider />
используетcontext
это实验性 API
Шерстяная ткань? 😱 На самом деле так и есть!provider
компонент хранит данные вcontext
середина,connect
Компоненты более высокого порядка изcontext
чтобы получить данные, так что,redux
не позволяет вашим данным быть доступными где бы то ни было,context
Вот и все.
Итак, зачем использоватьcontext
Шерстяная ткань? Может быть, все влюбились в него! даже если вы не используете его напрямуюcontext
, ваше приложение также будет передавать такие ссылки, какreact-redux,MobX-react,react-router,glamorousТакие сторонние библиотеки используют его косвенно.
Контекст возрождается
Теперь ясно, что мы так любимcontext
, но предупреждение из официальной документации все равно есть:在 React 的未来版本中,可能不再使用它
, хорошая новость заключается в том,context
Пришло время официально поздороваться со всеми, и вам, скорее всего, это понравится больше, чем когда-либо.
месяц назад,React 团队
отyarn,rustиEmberизrfcs 仓库
Вдохновил на создание собственногоrfcsсклад. склад первыйPR
отAndrew Clark(основной член команды React),PR
титулованныйNew version of context,вAndrew Clark
обрисовывает будущееcontext
Как это было, после этого было несколько интересных дискуссий, через несколько дней,Andrew Clark
кReact
На склад привезли одинNew context APIизPR
.
Итак, что именно изменилось? Визуально оцените новыеAPI
с предыдущимAPI
Различий миллионы. Вот простой, который я сделалПример
const ThemeContext = React.createContext('light')
class ThemeProvider extends React.Component {
state = {theme: 'light'}
render() {
return ThemeContext.provide(this.state.theme, this.props.children)
}
}
const ThemeConsumer = ({children}) => ThemeContext.consume(children)
class App extends React.Component {
render() {
<ThemeProvider>
<ThemeConsumer>{val => <div>{val}</div>}</ThemeConsumer>
</ThemeProvider>
}
}
Вы можете заметить, что в примере используется
render prop
, но на самом деле ничего не говорит о необходимости использованияrender prop
изcontext API
,ты можешь использоватьcontext API
легко реализовать高阶组件
или другие функции.
новыйcontext API
В основном он состоит из следующих трех частей
-
React.createContext
для доставки初始值
(по желаниюФантастическая функция отказа с использованием битовой маски), который возвращаетprovider
иconsumer
Объект -
provide
использование функцииhigher
, и может принимать любое значение -
consume
функционировать вprovider
использоваться где-либо впоследствии, и передать возвратJSX
функция (что немного похоже наrender prop
компоненты, ноconsume
не компонент).
я на этомAPI
полный ожиданий,React 团队
также будет удаленcontext 是实验性 API
предупреждение, так как теперь это кадрОсобенности первого класса. Это также означает, что люди не будут так беспокоиться об использованииcontext
решить приложениеprop-drilling
проблема, даRedux
также будет менее зависимым, даReact
понравится еще больше.
я видел недавно, что примерно означает:
Люди не очень хотят продолжать использовать
render
метод, отягчающийprop drilling
проблема, поэтому, наконец, хочу пройтиredux
чтобы облегчить
Поэтому я думаю, что если мы не уничтожим преждевременно или произвольноrender
метод, мы можем быть менее болезненными, даже если действительно нет способа избежать этого, в конце концов, мы можем пройти ядроReact API
решать.
Контекстная практика
я увиделcontext API
(или обычныйrender prop pattern
) много раз, как совместитьproviders
иconsumers
, когда вrender
способ поставить кучуrender prop
Когда компоненты собраны вместе, это выглядит таквложенный
Итак, что мы можем сделать, чтобы этого избежать? На самом деле, я лично не думаю, что это так уж плохо, если вы думаете, что это не хорошо, вы можете использовать обычные методы для ее решения:utility
функция/компонент, вот пример:
const ThemeContext = React.createContext('light')
class ThemeProvider extends React.Component {/* code */}
const ThemeConsumer = ({children}) => ThemeContext.consume(children)
const LanguageContext = React.createContext('en')
class LanguageProvider extends React.Component {/* code */}
const LanguageConsumer = ({children}) => LanguageContext.consume(children)
function AppProviders({children}) {
return (
<LanguageProvider>
<ThemeProvider>
{children}
</ThemeProvider>
</LanguageProvider>
)
}
function ThemeAndLanguageConsumer({children}) {
return (
<LanguageConsumer>
{language => (
<ThemeConsumer>
{theme => children({language, theme})}
</ThemeConsumer>
)}
</LanguageConsumer>
)
}
class App extends React.Component {
render() {
<AppProviders>
<ThemeAndLanguageConsumer>
{({theme, language}) => <div>{theme} and {language}</div>}
</ThemeAndLanguageConsumer>
</AppProviders>
}
}
Цель здесь состоит в том, чтобы использовать общие случаи в сочетании со специальными функциями/компонентами, чтобы сделать случаи более工程化
.
Кроме того, вы также можете обратиться кjmeasизreact-composer.
Но следует отметить, что на практике я не рекомендую вложенный рендеринг.props components
, вы можете создать несколько простых в использовании компонентов и комбинировать их в любое время.
Суммировать
Как сказано выше, яAPI
полный предвкушения. Еще не выпущено, но должно быть включено в следующийminor
версия. разные заботы, предыдущиеAPI
будет продолжать работать в обычном режиме до следующегоmajor
Версии выпускаются, так что у всех есть время мигрировать. И не забывайте,React
команда вFacebook
иметь больше, чем50,000
КусокReact components
Требуется техническое обслуживание, поэтому есть большая вероятность, что оно будет выпущено в будущем.codemod
Запустите автоматическое обновление кода большинства людей (как всегда).
я доволен этим新 API
в состоянии обеспечить, как яtwitterупоминается в.
Обратите внимание на публичный аккаунт WeChat: KnownsecFED, получайте больше качественной галантереи по коду!