(Переводчик) React ⚛️ Новый API контекста

внешний интерфейс React.js
(Переводчик) React ⚛️ Новый API контекста

Оригинальный адрес:⚛️ Новый контекстный 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 contextAndrew 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, получайте больше качественной галантереи по коду!