>  기사  >  웹 프론트엔드  >  React 16.3의 새로운 기능 분석

React 16.3의 새로운 기능 분석

小云云
小云云원래의
2018-02-09 15:36:454287검색

Context API는 항상 혼란스럽습니다. 이 API는 공식적인 API이지만 공식적으로는 이 API가 앞으로 바뀔 것이라고 말하면서 개발자가 이 API를 사용하는 것을 원하지 않습니다. 이제 그 변화가 필요한 때입니다. 새로운 API가 병합되었습니다. 그리고 더 "사용자 친화적"으로 보입니다. 특히 redux나 mobx를 사용해야 하는 경우 새로운 Context API를 선택하면 상태 관리가 더 간단해집니다.

새 API는 사용이 매우 간단합니다: React.createContext(), 따라서 두 개의 구성 요소가 생성됩니다. React.createContext(),这样就创建了两个组件:

import {createContext} from 'react';

const ThemeContext = createContext({
  background: 'yellow',
  color: 'white'
});

调用createContext方法会返回两个对象,一个是Provider,一个是Consumer

那个Provider是一个特殊的组件。它可以用来给子树里的组件提供数据。一个例子:

class Application extends React.Component {
  render() {
    <ThemeContext.Provider value={{background: &#39;black&#39;, color: &#39;white&#39;}}>
      <Header />
      <Main />
      <Footer />
    </ThemeContext.Provider>
  }
}

上例展示了如何传递“theme” context的。当然这些值可以是动态的(比如,基于this.state)。

下一步就是使用Consumer

const Header = () => {
  <ThemeContext.Consumer>
    {(context) => {
      return (
        <p style={{background: context.background, color: context.color}}>
          Welcome!
        </p>
      );
    }}
  </ThemeContext.Consumer>
}

如果在render Consumer的时候没有嵌套在一个Provider里面。那么就会使用createContext方法调用的时候设置的默认值。

注意:

  • Consumer必须可以访问到同一个Context组件。如果你要创建一个新的context,用的是同样的入参,那么这个新建的context的数据是不可访问的。因此,可以把Context当做一个组件,它可以创建一次,然后可以export,可以import。

  • 这个新的语法用了function as child模式(有时也叫做render prop模式)。如果不是很熟悉这个模式,那么推荐你看一下这些文章。

  • 新的API不再要求你声明contextProps了。

Context传递的数据和Context.Provider组件的value属性是一样的。对Provider数据的修改会引起所有的消费者(consumer)重绘。

新的声明周期方法

参考这个RFC。新的声明周期方法会被引入,而旧的会被废弃。

这一改变主要是为了强制推行最佳实践。你可以看看这篇文章来了解一下为什么这些生命周期方法会变得很诡异。这些最佳模式在React 16的异步绘制模式(Async Mode)下显得非常重要。

要被废弃的方法:

  • componentWillMount--使用componentDidMount代替

  • componentWillUpdate--使用componentDidUpdate代替

  • componentWillReceiveProps--使用一个新的方法:static getDerivedStateFromProps来代替。

不过这些并不会立刻发生,他们可以用到React 16.4。在React 17里将被彻底移除。如果你开启了StrictMode或者AsyncMode,可以通过这样的方式来使用,但是会收到警告:

  • UNSAFE_componentWillMount

  • UNSAFE_componentWillReceiveProps

  • UNSAFE_componentWillUpdate

static getDerivedStateFromProps

componentWillReceiveProps我们需要其他的方式根据props的变动更新state。社区决定引入一个新的static方法来处理这个问题。

什么是静态方法?一个静态方法就是存在于类内,而不是类的实例内的方法。静态方法访问不到this,并且在声明的时候有static关键字在前面修饰。

但是,问题来了。既然这个方法没有办法访问this,那么如何调用this.setState呢?答案就是,不调用。这个方法直接返回需要更新的state的数据,或者返回null,如果没有什么需要更新的话。

static getDerivedStateFromProps(nextProps, prevState) {
  if(nextProps.currentRow === prevState.lastRow) {
    return null;
  }

  return {
    lastRow: nextProps.currentRow,
    isCrollingDown: nextProps.curentRow > prevState.lastRow
  }
}

调用这个方法和之前调用this.setState的效果是一样的。只会修改这些返回的值,如果是null的话则不修改state。state的其他值都会保留。

值得注意的事

你需要定义初始state的值。无论是在constructor里,或者是类属性。否则会报警告。

这个方法getDerivedStateFromProps()会在第一次挂载和重绘的时候都会调用到,因此你基本不用在constructor里根据传入的props来setState

如果定义了getDerivedStateFromProps后,又定义了componentWillReceiveProps。那么,只有前者会被调用,并且你会收到一个警告。

一般你会使用一个回调来保证某些代码实在state更新之后才被调用的。那么,请把这些代码都移到componentDidUpdate里。

如果你不喜欢使用static

ComponentName.getDerivedStateFromProps = (nextProps, prevState) => {
  // Your code here
}
createContext 메서드를 호출하면 두 개의 개체가 반환됩니다. 공급자이고 다른 하나는 소비자입니다. 🎜🎜그 Provider는 특별한 구성 요소입니다. 하위 트리의 구성 요소에 데이터를 제공하는 데 사용할 수 있습니다. 예: 🎜
import {StrictMode} from 'react'

class Application extends React.Component {
  render() {
    return (
      <StrictMode>
        <Context.Provider value={{background: &#39;black&#39;, color: &#39;white&#39;}}>
          <Header />
          <Main />
          <Footer />
        </Context.Provider>
      </StrictMode>
    );
  }
}
🎜위의 예는 "테마" 컨텍스트를 전달하는 방법을 보여줍니다. 물론 이러한 값은 동적일 수 있습니다(예: this.state 기반). 🎜🎜다음 단계는 Consumer를 사용하는 것입니다. 🎜rrreee🎜Consumer를 렌더링할 때 Provider에 중첩되지 않은 경우. 그러면 createContext 메소드가 호출될 때 설정된 기본값이 사용됩니다. 🎜🎜참고: 🎜
  • 🎜소비자는 동일한 컨텍스트에 액세스할 수 있어야 합니다. 구성 요소. 새 컨텍스트를 생성하고 동일한 입력 매개변수를 사용하려는 경우 이 새 컨텍스트의 데이터에 액세스할 수 없습니다. 따라서 Context는 한 번 생성한 후 내보내고 가져올 수 있는 구성 요소로 간주할 수 있습니다. 🎜
  • 🎜이 새로운 구문은 함수를 하위 모드(렌더링 소품 모드라고도 함)로 사용합니다. 이 모델에 대해 잘 알지 못한다면 이 기사를 읽어 보시기 바랍니다. 🎜
  • 🎜새 API에서는 더 이상 contextProps를 선언할 필요가 없습니다. 🎜
🎜Context에 의해 전달된 데이터는 Context.Provider 구성 요소의 value 속성과 동일합니다. Provider 데이터를 수정하면 모든 소비자가 다시 그려집니다. 🎜

새로운 생명주기 방식

🎜 이 RFC를 참고하세요. 새로운 수명 주기 메서드가 도입되고 이전 메서드는 더 이상 사용되지 않습니다. 🎜🎜이 변경 사항은 주로 모범 사례를 시행하기 위한 것입니다. 이 기사를 읽고 이러한 수명 주기 메서드가 이상해지는 이유를 이해할 수 있습니다. 이러한 최상의 모드는 React 16의 비동기 그리기 모드(Async Mode)에서 매우 중요합니다. 🎜🎜지원 중단될 메소드: 🎜
  • 🎜comComponentWillMount--🎜
  • 대신 comComponentDidMount 사용
  • 🎜comComponentWillUpdate--🎜
  • 🎜comComponentWillReceiveProps 대신 comComponentDidUpdate 사용--새 메소드 사용: static getDerivedStateFromProps를 사용하세요. 🎜
🎜그러나 이것이 즉시 발생하지는 않으며 React 16.4를 사용할 수 있습니다. React 17에서는 완전히 제거됩니다. StrictMode 또는 AsyncMode를 활성화하면 이 방식으로 사용할 수 있지만 경고가 표시됩니다: 🎜
    🎜UNSAFE_comComponentWillMount🎜
  • 🎜UNSAFE_comComponentWillReceiveProps🎜
  • 🎜UNSAFE_comComponentWillUpdate🎜

static getDerivedStateFromProps

🎜 comComponentWillReceiveProps가 발생하는 경우 props 변경에 따라 상태를 업데이트하는 다른 방법이 필요합니다. 커뮤니티에서는 이 문제를 해결하기 위해 새로운정적 방법을 도입하기로 결정했습니다. 🎜🎜정적 메서드란 무엇인가요? 정적 메서드는 클래스 인스턴스 내에 존재하는 것이 아니라 클래스 내에 존재하는 메서드입니다. 정적 메서드는 this에 액세스할 수 없으며 선언 시 앞에 static 키워드로 수정됩니다. 🎜🎜하지만 여기서 문제가 발생합니다. 이 메소드는 this에 액세스할 방법이 없으므로 this.setState를 호출하는 방법은 무엇입니까? 대답은 전화하지 마세요입니다. 이 메서드는 업데이트해야 하는 상태 데이터를 직접 반환하거나, 업데이트할 항목이 없으면 null을 반환합니다. 🎜rrreee🎜이 메소드를 호출하면 이전에 this.setState를 호출한 것과 동일한 효과가 있습니다. 반환된 값만 수정됩니다. null인 경우 상태는 수정되지 않습니다. 다른 모든 상태 값은 유지됩니다. 🎜

주의할 점

🎜초기 상태의 값을 정의해야 합니다. 생성자 또는 클래스 속성으로. 그렇지 않으면 경고가 보고됩니다. 🎜🎜이 메소드 getDerivedStateFromProps()는 첫 번째 마운트 및 다시 그리기 중에 호출되므로 기본적으로 생성자에서 들어오는 props를 기반으로 setState를 수행할 필요가 없습니다. 🎜🎜getDerivedStateFromProps가 정의된 경우 comComponentWillReceiveProps가 정의됩니다. 그러면 전자만 호출되며 경고를 받게 됩니다. 🎜🎜일반적으로 콜백을 사용하여 상태가 업데이트될 때까지 특정 코드가 호출되지 않도록 합니다. 그런 다음 해당 코드를 모두 comComponentDidUpdate로 이동하세요. 🎜🎜 static 키워드를 사용하고 싶지 않다면 다음과 같이 하세요: 🎜
ComponentName.getDerivedStateFromProps = (nextProps, prevState) => {
  // Your code here
}

Static Mode

严格模式是一个新的方式来确保你的代码是按照最佳实践开发的。它实际是一个在React.StrictMode下的组件。它可以用在你的组件树的任何一部分上。

import {StrictMode} from 'react'

class Application extends React.Component {
  render() {
    return (
      <StrictMode>
        <Context.Provider value={{background: &#39;black&#39;, color: &#39;white&#39;}}>
          <Header />
          <Main />
          <Footer />
        </Context.Provider>
      </StrictMode>
    );
  }
}

如果一个在StricMode子树里的组件使用了componentWillMount方法,那么你会看到一个报错消息。

AsyncMode

异步模式在React.unsafe_AsyncMode下。使用AsncMode也会打开StrictMode模式下的警告。

相关推荐:

React 16.3之Context API详解


위 내용은 React 16.3의 새로운 기능 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.