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: 'black', color: 'white'}}> <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
当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: 'black', color: 'white'}}> <Header /> <Main /> <Footer /> </Context.Provider> </StrictMode> ); } }🎜위의 예는 "테마" 컨텍스트를 전달하는 방법을 보여줍니다. 물론 이러한 값은 동적일 수 있습니다(예:
this.state
기반). 🎜🎜다음 단계는 Consumer
를 사용하는 것입니다. 🎜rrreee🎜Consumer
를 렌더링할 때 Provider
에 중첩되지 않은 경우. 그러면 createContext
메소드가 호출될 때 설정된 기본값이 사용됩니다. 🎜🎜참고: 🎜contextProps
를 선언할 필요가 없습니다. 🎜Context.Provider
구성 요소의 value
속성과 동일합니다. Provider
데이터를 수정하면 모든 소비자가 다시 그려집니다. 🎜comComponentWillMount
--🎜comComponentDidMount
사용 comComponentWillUpdate
--🎜comComponentWillReceiveProps
대신 comComponentDidUpdate
사용--새 메소드 사용: static getDerivedStateFromProps를 사용하세요. 🎜StrictMode
또는 AsyncMode
를 활성화하면 이 방식으로 사용할 수 있지만 경고가 표시됩니다: 🎜UNSAFE_comComponentWillMount
🎜UNSAFE_comComponentWillReceiveProps
🎜UNSAFE_comComponentWillUpdate
🎜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 }
严格模式是一个新的方式来确保你的代码是按照最佳实践开发的。它实际是一个在React.StrictMode
下的组件。它可以用在你的组件树的任何一部分上。
import {StrictMode} from 'react' class Application extends React.Component { render() { return ( <StrictMode> <Context.Provider value={{background: 'black', color: 'white'}}> <Header /> <Main /> <Footer /> </Context.Provider> </StrictMode> ); } }
如果一个在StricMode
子树里的组件使用了componentWillMount
方法,那么你会看到一个报错消息。
异步模式在React.unsafe_AsyncMode
下。使用AsncMode
也会打开StrictMode
模式下的警告。
相关推荐:
위 내용은 React 16.3의 새로운 기능 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!