目前可以试用alpha版本,正式版会在近期发布
{
"dependencies": {
"react": "^16.3.0-alpha.0",
"react-dom": "^16.3.0-alpha.0"
}
}
新的context
context这个特性已经存在很久了,但因为一些原因一直是处于试验性质的API。 React 16.3带来了正式版的context API
- 用
createContext
创建一个context,context里有Provider
和Consumer
两个组件
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>
当你在严格模式下使用了不建议的函数,你会得到一个警告信息
同样的unsafe_AsyncMode
现在暂时没有用,用于未来的异步渲染
看到一篇文章说,其实现在 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相关实践也算是比较成熟了