10-组件通信
3.3 组件通信
当构建简单的评论框组件时,我们已经看到能够用其他组件创建组件。这是React特别棒的原因之一。开发人员能够轻易地用子组件构建其他组件,与此同时还能够保持事物良好地捆绑在一起,并且还能很容易地表示组件间的is-a和has-a关系。这意味着可以将组件看作组件的一部分或是一种特定的东西。
能够混合和匹配组件并灵活地构建东西是很棒的,但如何让它们彼此通信呢?许多框架和库提供了框架特有的方法让应用的不同部分彼此通信。Angular.js或Ember.js中,你可能听说过或曾经使用服务在应用的不同部分之间进行通信。通常这些是广泛可用的长期对象,开发人员可以在其中存储状态并从应用的不同部分进行访问。
React使用了服务或类似的东西吗?没有。在React中,如果想让组件彼此通信,需要传递属性,并且当传递属性时,开发人员做了两件简单的事情:
- 访问父组件中的数据(要么是状态要么是属性);
- 传递数据给子组件。
代码清单3-6的示例既展示了你熟悉的父子关系,也展示了所属关系。你可以前往https://codesandbox.io/s/ pm18mlz8jm运行代码。
代码清单3-6 从父组件向子组件传递属性
import React from "react";
import { render } from "react-dom";
import PropTypes from "prop-types";
const UserProfile = props => { ⇽--- 创建一个返回示例图片的无状态函数组件
return <img src={`https://*******.*******.com/user/${props.username}`} />;
};
UserProfile.propTypes = {
pagename: PropTypes.string ⇽--- 记住,即使是在无状态函数组件上,仍可以指定默认属性和propTypes
};
UserProfile.defaultProps = {
pagename: "erondu" ⇽--- 记住,即使是在无状态函数组件上,仍可以指定默认属性和propTypes
};
const UserProfileLink = props => {
return <a href={`https://ifelse.io/${props.username}`}>{
props.username}</a>;
};
const UserCard = props => { ⇽--- UserCard是UserProfile和UserProfileLink的父组件
return (
<div>
<UserProfile username={props.username} />
<UserProfileLink username={props.username} />
</div>
);
};
render(<UserCard username="erondu" />, document.getElementById("root"));