React从入门到精通系列之(20)用上下文管理应用
二十、用上下文管理应用使用React可以很容易通过React组件跟踪数据流。 当你看到一个组件,你就可以看到哪些 在某些情况下,你希望通过组件树传递数据,而不是在每个级别的中组件手动传递 为什么不去使用Context绝大多数的应用不需要直接使用Context。 如果你希望你的应用是稳定的,那么就不要使用Context。 因为这是一个实验性质的API,它可能会在未来的React版本中移除。 如果你不熟悉state管理库如 如果你不是一个有经验的React开发人员,不要使用Context。 使用 尽管有上面这些警告你还坚持使用Context,那么请将Context单独隔离到一个小区域中,并尽可能地避免直接使用Context,以便在这个API更改时应用能更容易升级。 如何使用Context假设你有一个结构: import React from 'react';
import ReactDOM from 'react-dom';
class MyButton extends React.Component {
constructor(props) {
super(props);
}
render() {
const style = {backgroundColor: this.props.color};
return <button style={style}>{this.props.children}</button>;
}
}
class Message extends React.Component {
render() {
return (
<div>
{this.props.text}
<MyButton color={this.props.color}>删除</MyButton>
</div>
)
}
}
class MessageList extends React.Component {
render() {
const color = 'red';
const children = this.props.messages.map(msg => <Message text={msg} color={color}/>);
return <div>{children}</div>;
}
}
const messages = ['zhangyato','Re: zhangyatao','Re:Re:zhangyatao'];
ReactDOM.render(
<MessageList messages={messages}/>,document.getElementById('root')
);
在这个例子中,我们手动传入一个 import React from 'react';
import ReactDOM from 'react-dom';
class MyButton extends React.Component {
constructor(props) {
super(props);
}
render() {
const style = {backgroundColor: this.context.color};
return <button style={style}>{this.props.children}</button>;
}
}
MyButton.contextTypes = {
color: React.PropTypes.string.isRequired
};
class Message extends React.Component {
render() {
return (
<div>
{this.props.text}
<MyButton>删除</MyButton>
</div>
)
}
}
class MessageList extends React.Component {
getChildContext() {
return {color: 'red'};
}
render() {
const children = this.props.messages.map(msg => <Message text={msg}/>);
return <div>{children}</div>;
}
}
MessageList.childContextTypes = {
color: React.PropTypes.string.isRequired
};
const messages = ['zhangyato',document.getElementById('root')
);
通过向 如果未定义 父子组件之间的耦合Context还可以让你实现父组件和子组件之间的交互。 例如,以这种方式工作的一个比较知名的库为 const RouterExample = () => {
<Router>
<div>
<ul>
<li><Link to="/">主页</Link></li>
<li><Link to="/recyclebin">回收站</Link></li>
<li><Link to="/timeline">图片</Link></li>
</ul>
<hr />
<Match exactly pattern="/" component={Home} />
<Match pattern="/recyclebin" component={RecycleBin} />
<Match pattern="/timeline" component={TimeLine} />
</div>
</Router>
}
通过从 在使用类似于此的API进行构建组件之前,请考虑是否有更好的替代品。 例如,你可以传递整个React组件作为props。 生命周期方法中使用Context如果在一个组件中定义了
在无状态功能性组件中使用Context如果 function MyButton(props,context) {
const children = props.children;
return (
<button style={{backgroundColor: context.color}}>
{children}
</button>
);
}
MyButton.contextTypes = {
color: React.PropTypes.string.isRequired
};
更新Context千万不要这么做!!! React有一个API来更新Context,但它从根本上破坏了Context,所以你不应该使用它。 当state或props改变时, import React from 'react';
import ReactDOM from 'react-dom';
class MediaType extends React.Component {
render() {
return <div>type is {this.context.type}</div>
}
}
MediaType.contextTypes = {
type: React.PropTypes.string
};
class MediaQuery extends React.Component {
constructor(props) {
super(props);
this.state = {type: 'PC端'};
this.checkMediaQuery = this.checkMediaQuery.bind(this);
}
getChildContext() {
return {type: this.state.type}
}
checkMediaQuery() {
let type = window.matchMedia('<code>zhangyatao</code>(max-width: 760px)').matches ? '移动端' : 'PC端';
this.setState({type: type});
}
componentDidMount() {
window.addEventListener('resize',this.checkMediaQuery,false);
this.checkMediaQuery();
}
render() {
return <div>{this.props.children}</div>;
}
}
MediaQuery.childContextTypes = {
type: React.PropTypes.string
};
ReactDOM.render(
<MediaQuery>
<MediaType />
</MediaQuery>,document.getElementById('root')
);
问题是,Context的值通过组件更新来提供,如果中间的父组件在 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
