共计 1995 个字符,预计需要花费 5 分钟才能阅读完成。
props
当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)转换为单个对象传递给组件,这个对象被称之为“props”。
function Welcome(props) {return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
React 调用 Welcome 组件,并将 {name: ‘Sara’} 作为 props 传入。
注意:组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props。
context
在一个典型的 React 应用中,数据是通过 props 属性自上而下(由父及子)进行传递的。但是如果有些属性是应用程序中许多组件都需要的,此时我们希望可以共享这些值,于是 Context 就出现了。
Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props。
Context 就像我们在应用中使用全局变量一样。我们应当谨慎使用 Context。
var Button = React.createClass({
contextTypes: {color: React.PropTypes.string},
render: function() {
return (<button style={{background: this.context.color}}>
{this.props.children}
</button>
);
}
});
var Message = React.createClass({render: function() {
return (
<div>
{this.props.text} <Button>Delete</Button>
</div>
);
}
});
var MessageList = React.createClass({
childContextTypes: {color: React.PropTypes.string},
getChildContext: function() {return {color: "purple"};
},
render: function() {
return (
<div>
<Message text='警告'/>
</div>
);
}
});
在这个例子中,我们想在 MessageList 组件中,传递 color 值到子组件 Message 的子组件 Button 中(即越级传值),需要以下步骤。
首先,我们需要在 MessageList 组件中定义 childContextTypes 和 getChildContext。
其次,我们需要在 Button 组件中定义 contextTypes。
这样我们就可以在 Button 组件中使用这些值了。
备注:React 能够自动地把信息 (数据) 向所有设置了 contextTypes 的子树进行传递。如果 contextTypes 在子组件中还没有定义,那 this.context 将会是一个空对象。
那我们应该怎么更新组件的 Context 呢?
答案是,把 Context 和组件的 State 关联起来,当组件的 state 或者 props 改变的时候,getChildContext 函数会自动调用,更新 Context 并把这个新的 Context 和其他改变一起传输到子树。
var MediaQuery = React.createClass({getInitialState: function(){return {type:'desktop'};
},
childContextTypes: {type: React.PropTypes.string},
getChildContext: function() {return {type: this.state.type};
},
componentDidMount: function(){var checkMediaQuery = function(){var type = window.matchMedia("(min-width: 1025px)").matches ? 'desktop' : 'mobile';
if (type !== this.state.type){this.setState({type:type});
}
};
window.addEventListener('resize', checkMediaQuery);
checkMediaQuery();},
render: function(){return this.props.children;}
});
其实在大多数情况下,为了代码的清晰可观,我们都应该尽可能避免使用 Context(就像全局变量一样)。Context 的最佳应用情景应该是像用户登录、应用语言或者是应用主题的这一类情景,这些都是真实的全局变量。