Почему React 16 — благо для разработчиков

React.js

Переводчик: Front-end Xiaozhi

оригинал:medium.free код camp.org/why-react16…

Ставь лайк и смотри, поиск в WeChat【Переезд в мир】Обратите внимание на этого человека, который не имеет большого фабричного прошлого, но имеет восходящий и позитивный настрой. эта статьяGitHub GitHub.com/QQ449245884…Он был включен, статьи были классифицированы, и многие мои документы и учебные материалы были систематизированы.

Все говорили, что нет проекта для написания резюме, поэтому я помог вам найти проект, и это было с бонусом.【Учебник по строительству】.

Ниже приведены некоторые полезные функции, которые следует учитывать при переносе существующего приложения с React 15 на React 16.

Чтобы читать больше качественных статей, пожалуйстаПосетите блог GitHub100 статьи в год высококачественных статей ждет вас!

обработка ошибок

React 16 представляет новую концепцию границ ошибок.

Теперь в React 16 вы можете использовать функцию границы ошибки вместо того, чтобы размонтировать всю программу, как только возникает ошибка. Думайте о границах ошибок как о механизме, похожем на операторы try-catch в программировании, но реализуемом компонентами React.

Error Boundary — это компонент React. Он и его подкомпоненты образуют древовидную структуру, которая ловит ошибки повсюду в JavaScript, регистрирует их, а также отображает резервный интерфейс, который не позволяет пользователям напрямую видеть сообщения о сбоях в дереве компонентов.

Это включает в себя новую функцию жизненного цикла, называемуюcomponentDidCatch(error, info). Независимо от того, какой компонент класса, пока эта функция определена, она становится границей ошибки.

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    // Display fallback UI
    this.setState({ hasError: true });
    // 你还可以将错误记录到错误报告服务中
    logErrorToMyService(error, info);
  }

  render() {
    if (this.state.hasError) {
      // 可以渲染任何自定义回退界面
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

Он может использоваться в качестве обычных компонентов:

<ErrorBoundary>  
   <MyWidget />
</ErrorBoundary>

componentDidCatch()catch{}Блок, но это работает для компонентов. Только классы могут быть границы ошибок. На самом деле, в большинстве случаев вы хотите один раз объявить границу ошибки, а затем использовать его во всем приложении.

осторожностьГраница ошибки будет захватывать компоненты, расположенные под ними по ошибке. Граница ошибки не может зафиксировать свои собственные ошибки. Если сообщение об ошибке не приводит к ошибкам рендеринга границы, ошибки распространяются на ближайшую ошибку границы выше. Это также похоже на блок catch {} в JavaScript.

Официальный сайт.

Новые типы возврата рендеринга: фрагмент и строка

Теперь вы можете избавиться от упаковки компонента вdivсередина.

Теперь вы можете вернуть массив элементов из метода рендеринга компонента. Как и в случае с другими массивами, вам нужно добавить ключ к каждому элементу, чтобы избежать ключевых предупреждений:

render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}

Начиная с Реагировать 16.2.0, который поддерживает специальный синтаксис фрагментов JSX, не требующий ключей.

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}

Поддерживает возвращаемые строки:

render() {
  return 'Look ma, no spans!';
}

Portal

Портал предоставляет узел dom, который отображает дочерние узлы из родительского узла.

ReactDOM.createPortal(child, container)

Первый параметр (child)是任何可渲染的 React子元素,例如元素,字符串或片段。 второй параметр(container)это элемент DOM.

как это использовать

В версии React15.X мы можем только сказать, что дочерние узлы отображаются в родительских узлах.Основное использование выглядит следующим образом:

render() {
  // React需要创建一个新的div来包含子节点
  return (
    <div>
      {this.props.children}
    </div>
  );
}

Но если вам нужно вставить дочерний узел в DOM вне родительского узла, React15.x и более ранние версии не предоставляли API для этой функции. Портал в React 16.0 можно использовать:

render() {
  // React不需要创建一个新的div去包含子元素,直接将子元素渲染到另一个
  //dom节点中
  //这个dom节点可以是任何有效的dom节点,无论其所处于dom树中的哪个位置 

  return ReactDOM.createPortal(
    this.props.children,
    domNode,
  );
}

Типичный вариант использования Portal таков: когда родительский компонент имеетoverflow:hiddenилиz-indexПри стилизации, вы хотите, чтобы дочерний компонент визуально «вырвался» его контейнера. Например, диалоговые окна, катки на курсе и подсказки.

Пользовательские свойства DOM

// 你的代码
<div mycustomattribute="something" />

// React 15 output:
<div />

В React 16 вывод будет следующим (будет отображаться пользовательское свойство, и оно не будет игнорироваться)

// React 16 output:
<div mycustomattribute="something" />

Установите null в состоянии, чтобы избежать повторного рендеринга

Иногда нам нужно использовать функцию, чтобы определить, вызывает ли обновление состояния компонента повторный рендеринг.В React 16 мы можем вызватьsetStateКогда входящийnullчтобы избежать повторного рендеринга компонента, что означает, что мы можем решить, нужно ли обновлять наше состояние внутри метода setState,

const MAX_PIZZAS = 20;

function addAnotherPizza(state, props) {
  // Stop updates and re-renders if I've had enough pizzas.
  if (state.pizza === MAX_PIZZAS) {
    return null;
  }

  // If not, keep the pizzas coming! :D
  return {
    pizza: state.pizza + 1,
  }
}

this.setState(addAnotherPizza);

Для получения дополнительной информации, пожалуйста, прочитайтездесь

создать ссылку

Теперь создано с помощью React16refsЭто намного проще. Почему вы должны использовать?refs:

  • Управляйте фокусом, выделением текста или воспроизведением мультимедиа.

  • Запустить анимацию.

  • Интеграция DOM со сторонними библиотеками.

refэто использоватьReact.createRef()Созданrefref

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }

  render () {
    return <div ref={this.myRef}></div>
  }
}

посетите исх.

Вышеупомянутое для созданияRefметод, указанный в компоненте, указанном Ref, вrenderЕго можно вызвать после того, как React16.3 предоставляетcurrentатрибут, для справкиrenderУзел после:

componentDidMount(){
  console.log(this.myRef.current);
  //render之后就可以输出该ref指向的那个节点
}

Кроме того, узел, на который указывает один и тот же Ref, может быть узлом dom или компонентом класса.

Значение Ref варьируется в зависимости от типа узла:

  • Когда атрибут REF используется на HTML-элементе, REF, созданный с помощью RACT.CREATEREF () в конструкторе, имеет основной элемент DOM в качестве текущего атрибута.

  • Когда атрибут ref используется для пользовательского компонента класса, объект ref имеет смонтированный экземпляр компонента в качестве текущего атрибута.

  • Вероятно, вы не будете использовать атрибут ref для функциональных компонентов, потому что у них нет экземпляров.

Context API

Контекст предоставляет способ передачи данных через дерево компонентов без необходимости передавать их вручную на каждом уровне.prop.

React.createContext

const { Provider, Consumer } = React.createContext(defaultValue)

Создайте{Provider,Consumer}правильно.当 React 渲染 Consumer 时,它将从树中最接近的 Provider 读取当前上下文值。

defaultValueПараметры используются только тогда, когда потребитель не может найти соответствующий провайдер в дереве, который полезен при тестировании компонентов индивидуально. Обратите вниманиеundefinedПередача в качестве значения Provider не приводит к тому, что Потребитель используетdefaultValue.

Provider

<Provider value={/* some value */}>

Актуальный компонент, который позволяет потребителям подписаться на изменения контекста.

Consumer

<Consumer>
  {value => /* render something based on the context value */}
</Consumer>

Providerизvalue.如果没有匹配的 Provider,则valuecreateContext()ЗНАЧЕНИЕ ПО УМОЛЧАНИЮ.

static getDerivedStateFromProps()

Длительное время,componentWillReceivePropsэто единственный способ обновить состояние без дополнительного рендеринга.

В версии 16.3 мы введем новую функцию жизненного циклаgetDerivedStateFromPropsзаменитьcomponentWillReceivePropsи обрабатывать тот же сценарий более безопасным способом.

В то же время мы поняли, что существует много непонимания того, как использовать оба метода, и мы обнаружили некоторые анти-шаблоны, которые приводили к тонким и запутанным ошибкам.

В 16.4, оgetDerivedStateFromPropsИсправление делает производное состояние более предсказуемым, поэтому последствия неправильного использования легче заметить.

getDerivedStateFromPropsбуду звонитьrenderМетод вызывается ранее, он должен вернуть объект, используемый для обновления состояния или возврата, если какой-либо статус не обновляетсяnull.

Этот подход работает для некоторых редких случаев использования, когдаstateполагатьсяpropИзменение. Например, удобно реализовать<Transition>компонент, он сравнивает предыдущий и следующий дочерние компоненты и решает, какой из них нужно анимировать.

Производное состояние может привести к многословному коду и затруднить разработку и поддержку ваших компонентов.

Вы можете рассмотреть более простые альтернативы:

* Если вы хотите «сбросить» какое-либо состояние при изменении реквизита, рассмотрите возможность создания контролируемых компонентов или неконтролируемых компонентов с ключами.

  • Этот метод не имеет доступа к экземпляру компонента. Если вы хотите, вы можете извлечь компоненты с помощьюpropsчистые функции и состояния вне определений классов, вgetDerivedStateFromProps()и повторно использовать некоторый код между другими методами класса.

Уведомление, однако этот метод будет срабатывать каждый раз при выполнении рендеринга. Это то же самое, чтоUNSAFE_componentWillReceivePropsсовершенно противоположно. Он срабатывает только при повторном рендеринге родительского компонента, а не как локальный.setStateрезультат.

БудуnextProps.someValueСравните с this.props.someValue. Если оба разные, то делаем что-то:

static getDerivedStateFromProps(nextProps, prevState){   
  if(nextProps.someValue!==prevState.someValue){     
    return { someState: nextProps.someValue};  
   }
   return null
}

Он принимает два параметраnextPropsа такжеprevState.如前所述,你无法在这个方法中访问this.你必须将 prop 存储在 state 中,然后将nextPropsВ отличие от предыдущей опоры. В приведенном выше коде сравниваются nextProps и prevState. Если они разные, верните объект для обновления состояния, в противном случае верните null, указывающий, что состояние не нужно обновлять. Если состояние изменяется, вызывается componentDidUpdate, и мы можем делать то, что хотим, как в componentWillReceiveProps.

Реагировать на события жизненного цикла

Rect V16.3, самое большое изменение, чем жизненный цикл, чтобы удалить следующие три:

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

  • static getDerivedStateFromProps

  • getSnapshotBeforeUpdate

зачем менять

Старый жизненный цикл очень полный, и он может в основном фиксировать каждое состояние/реквизит/ссылку, обновленное компонентом, без каких-либо логических проблем.

Однако об этом не известно самому чиновнику, и React намерен запустить новый асинхронный рендеринг в версии 17, и предложить жизненный цикл, который можно прервать, а этап, который можно прервать, — это этап сборки виртуального DOM перед фактическое монтирование DOM, а также удаление трех жизненных циклов.

После прерывания жизненного цикла предыдущий жизненный цикл будет запущен снова при следующем возобновлении, поэтому componentWillMount, componentWillReceiveProps и componentWillUpdate не могут гарантировать, что они будут обновлены только один раз при монтировании/получении реквизитов/изменении статуса, поэтому эти три метода помечены как небезопасные.

Ваши лайки - моя мотивация продолжать делиться хорошими вещами, ставьте лайки!

общаться с

Статья постоянно обновляется каждую неделю. Вы можете выполнить поиск «Big Move to the World» в WeChat, чтобы прочитать и обновить ее как можно скорее (на одну или две статьи раньше, чем в блоге). Эта статья находится на GitHub.GitHub.com/QQ449245884…Он был включен, и многие мои документы были разобраны. Добро пожаловать в Звезду и совершенство. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Кроме того, обратите внимание на паблик-аккаунт и ответьте в фоновом режиме.Благосостояние, вы можете увидеть преимущества, вы знаете.