React 16.3(.0-alpha)新特性

React 16.3-alpha已经发布。这次发布都有哪些新特性呢,我们来一起看看。

新的Context API

Context API总是很让人迷惑。这个API是官方的,但是官方又不希望开发者们使用这个API,说是这个API会在以后发生改变。现在就是那个改变的时刻。新的API已经被merge了。而且它看起来更加的“用户友好”了。尤其是你不得不使用redux、mobx的时候,可以选择新的Context API实现更加简单的状态管理。

新的API用起来非常的简单: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 (
        <div style={{background: context.background, color: context.color}}>
          Welcome!
        </div>
      );
    }}
  </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
}

Static Mode

严格模式是一个新的方式来确保你的代码是按照最佳实践开发的。它实际是一个在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方法,那么你会看到一个报错消息。

AsyncMode

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

如果你想学习更多异步模式的内容,你可以在下面的地方看到更多的文章和示例:

新版React Developer Tools

这个作者发文的时候居然是Firefox支持了最新版的React。而Chrome还木有。。。

原文地址:https://medium.com/@baphemot/whats-new-in-react-16-3-d2c9b7b6193b

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容

  • It's a common pattern in React to wrap a component in an ...
    jplyue阅读 3,267评论 0 2
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,657评论 18 139
  • 深入JSX date:20170412笔记原文其实JSX是React.createElement(componen...
    gaoer1938阅读 8,065评论 2 35
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,138评论 25 707
  • new 修饰符与 new 操作符是两个概念 new 修饰符用于声明类或类的成员,表示隐藏了基类中同名的成员。而ne...
    viva158阅读 751评论 0 0