React 16.3快要发布了,新的context API有望替代redux?
发布于 8 年前 作者 dislido 10851 次浏览 来自 分享

AV(}EZ[~3SZ2MZZ04]D8%4B.png 目前可以试用alpha版本,正式版会在近期发布

{
 "dependencies": {
 "react": "^16.3.0-alpha.0",
 "react-dom": "^16.3.0-alpha.0"
 }
}

新的context

context这个特性已经存在很久了,但因为一些原因一直是处于试验性质的API。 Y`FREBA{_39OOL4_LT)HNX6.png React 16.3带来了正式版的context API

  • createContext创建一个context,context里有ProviderConsumer两个组件
import React, { createContext } from 'react';
const ctx = createContext({
 text: 'hello world!',
});
const { Provider, Consumer } = ctx;

Provider组件用于将context数据传给该组件树下的所有组件 value属性是context的内容

class App extends React.Component {
 render() {
 return (
 <Provider value={{ text: 'hello react!' }}>
 <Comp1 />
 <Comp2 />
 </Provider>
 );
 }
}

要使用context的数据,我们需要使用Consumer组件

// 函数式
const Comp1 = () => (
 <Consumer>
 {context => <p>{context.text}</p>}
 </Consumer>
);
// 类
class Comp2 extends React.Component {
 render() {
 return (
 <Consumer>
 {context => <p>{context.text}</p>}
 </Consumer>
 );
 }
}

可以发现Consumer使用了将一个函数作为它的children的新语法,从上面的例子中可以看出它接收context并将context.text渲染出来
Consumer下不能写其它的东西,比如<Consumer>text: {context => <p>{context.text}</p>}</Consumer>
另外,在新的context API下,我们不需要写contextProps就能使用context了

等等,既然context的内容是写在Provider的value中,那我们创建context时的参数呢? 如果你没有将Consumer作为Provider的子组件,那么Consumer将使用创建context时的参数作为context

更新context

更新context很容易

class App extends React.Component {
 constructor(props) {
 super(props);
 this.state = {
 text: 'hello react!',
 };
 }
 updateCtx() {
 this.setState({ text: 'updated!' });
 }
 render() {
 return (
 <Provider value={this.state}>
 <button onClick={() => this.updateCtx()}>update</button>
 <Consumer>
 {context => <p>{context.text}</p>}
 </Consumer>
 </Provider>
 );
 }
}

新的context提供了一个简洁的管理全局状态的方式,或许可以替代Redux之类的状态管理库?

生命周期相关改动

为了支持未来的异步渲染特性,以下生命周期函数将被废弃

  • componentWillMount 请使用 componentDidMount代替
  • componentWillUpdate 请使用 componentDidUpdate代替
  • componentWillReceiveProps 请使用新增的 static getDerivedStateFromProps代替
    废弃警告会在React 16.4开启,废弃的函数预计在React 17.0移除

static getDerivedStateFromProps

作为被废弃的componentWillReceiveProps的替代,React提供了一个新的函数static getDerivedStateFromProps(nextProps, prevState)
注意前面的static,这意味着在这个函数中我们不能使用this, 该函数的返回值将用于更新state。如果不需要更新state,就返回null

static getDerivedStateFromProps(nextProps, prevState) {
 if (nextProps.text === prevState.text) return null;
 return { text: nextProps.text }; // 相当于setState({ text: nextProps.text });
}

严格模式和异步模式

import React, { StrictMode } from 'react';
// ...
<StrictMode>
 // ...
</StrictMode>

当你在严格模式下使用了不建议的函数,你会得到一个警告信息 image.png 同样的unsafe_AsyncMode现在暂时没有用,用于未来的异步渲染

6 回复

看到一篇文章说,其实现在 Redux 使用的就是 这个 context API.
按照示例来理解, 在一个应用中可以创建多个 context, 对应Redux,实际就是一个只用了一个context(state tree). 对应的 flux 构架应该就是可以使用多个context(多个 store).

@phpsmarter 不是redux使用这个api,是react-redux使用的

生命周期相关改动,不理解啊 「 componentWillUpdate 请使用 componentDidUpdate代替 」 意思都不一样啊

@hi363138911 像这样改写

componentWillUpdate(nextProps, nextState) {
 foo(nextProps, nextState);
 bar(this.props, this.state);
 nextProps.a === this.props.a;
}
componentDidUpdate(prevProps, prevState) {
 foo(this.props, this.state);
 bar(prevProps, prevState);
 this.props.a === prevProps.a;
}

context其实以前也一直有用,甚至还有自己实现的context为了防止被官方弃用了。 现在官方正式接受了倒也是好事。 不过和redux比的话,目前感觉他们方式还是有区别的,redux相关实践也算是比较成熟了

这里有个解释: https://www.reddit.com/r/reactjs/comments/84d4m5/heres_how_reacts_new_context_api_works_by_wes_bos/dvozsxx/ FireShot Capture 13 - BTMPL 對 Heres how React's New Context _ - https___www.reddit.com_r_reactjs_c.png

回到顶部

AltStyle によって変換されたページ (->オリジナル) /