组件使 UI 分离为独立可服用的块,可隔离思考每个块。这页介绍组件理念。在此查阅 组件 API 参考。javascript
概念上讲,组件与 JavaScript 函数相像。他们接受任意输入(称为 "props") 而后返回描述屏幕上显示的 React elements 。html
定义一个组件最简单的方式是写一个 JavaScript 函数:java
function Welcome(props) { return <h1>Hello, {props.name}</h1>; }
这个函数是一个有效的 React component 由于它接受了单一的 "props"(这个是 properties 的缩写)对象数据参数且返回了一个 React element. 咱们称这样的组件为 "functional" 由于他们就是 JavaScript functions 的字面含义。react
也可使用 ES6 class 来定义一个组件:api
class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } }
以上两种组件对 React 来讲没有区别。数组
classes 有额外的特色咱们[下一部分]()讨论。在那以前,简明旗舰咱们使用函数组件。网络
以前,咱们只鼓励 React elements 呈现 DOM 标签:函数
const element = <div />;
然而, elements 也能呈现自定义组件:网站
const element = <Welcome name="Sara" />;
当 React 发现一个 element 呈现用户自定义组件,它会将 JSX 属性作为单个对象传递到这个组件。 咱们称这个对象 "props".this
例如: 这个代码在页面渲染出 "Hello, Sara":
function Welcome(props) { return <h1>Hello, {props.name}</h1>; }
扼要重述例子中发生了什么:
Note: 组件命名以大写字母开头。
React 将小写开头的组件当作 DOM 标签处理。例如, <div /> 表示一个 HTML div 标签, 可是 <Welcome /> 表示一个组件并且须要 Welcome 在其以内。
组件能够指它们输出中的其余组件。这使得能够在任意细节层级使用一样的组件。 按钮、表单、对话框、屏幕:在 React 应用,以上这些都统称为组件。
例如,能够建立一个 App 组件屡次渲染 Welcome:
function Welcome(props) { return <h1>Hello, {props.name}</h1>; } function App() { return ( <div> <Welcome name="Sara" /> <Welcome name="Cahal" /> <Welcome name="Edite" /> </div> ); } ReactDOM.render( <App />, document.getElementById('root') );
典型的,新 React 应用有单独一个 App 组件在最外层。然而整合 React 到一个已有的应用,你应该从一个相似 Button 的小组件开始, 渐渐扩展到最上层视图层级。
不要惧怕吧组件粉等更小的组件。
例如, 思考 Comment 组件:
function Comment(props) { return ( <div className="Comment"> <div className="UserInfo"> <img className="Avatar" src={props.author.avatarUrl} alt={props.author.name} /> <div className="UserInfo-name"> {props.author.name} </div> </div> <div className="Comment-text"> {props.text} </div> <div className="Comment-date"> {formateDate(props.date)} </div> </div> ); }
组件接受 author(对象), text(字符串)和 date(日期) 做为 props, 描绘一个 评论界面到社交网站上。
这个组件修改须要技巧由于全部嵌套很难复用独立的部分。咱们从中提取一些组件出来。
第一步咱们提取 Avatar:
function Avatar(props) { return ( <img className="Avatar" src={props.user.avatarUrl} alt={props.user.name} /> ); }
Avatar 不须要知道它被渲染在一个 Comment中。这是为何咱们给它的 prop 取一个通用的名字: user 而不是 author.
咱们建议为组件 props 命名从组件自身角度出发,而不是内容在哪里使用。
咱们还能够简化 Comment 一点:
function Comment(props) { return ( <div className="Comment"> <div className="UserInfo"> <Avatar user={props.author} /> <div className="UserInfo-name"> {props.author.name} </div> </div> <div className="Comment-text"> {props.text} </div> <div className="Comment-date"> {formateDate(props.date)} </div> </div> ); }
接下来,我么提取一个 UserInfo 组件紧邻用户的名称来渲染 Avatar :
function UserInfo(props) { return ( <div className="UserInfo"> <Avatar user={props.user} /> <div className="UserInfo-name"> {props.user.name} </div> </div> ); }
更近一步简化 Comment :
function Comment(props) { return ( <div className="Comment"> <UserInfo user={props.author} /> <div className="Comment-text"> {props.text} </div> <div className="Comment-date"> {formateDate(props.date)} </div> </div> ); }
提取组件看起来枯燥无味,可是一版可复用组件在一个较大的应用中回报丰厚。
好的标准是一部分你的 UI 被屡次应用(Button, Panel, Avatar), 或者它足够复杂(App, FeedStory, Comment), 成为一个可复用的组件是个好的选择。
不论你以函数仍是类的方式声明一个组件,它必须从不修改它的 props. 思考许下 sum 函数:
function sum(a, b) { return a + b; }
相似的函数被成为 "pure(纯)" ,由于他们不尝试修改他们的输入,并且他们根据相同的输入返回相同的输出。
相反, 下面这个函数就不是纯函数,由于它修改了本身的入参。
function withdraw(account, amount) { account.total -= amount; }
React 至关灵活可是它有一个严格的规则:
全部 React 组件必须想一个纯函数同样对待它们的 props.
固然, 应用 UI 随时间动态改变。下一部分,介绍一个新概念 "state".
State 使得 React 组件能够在响应用户行为,网络请求或任何东西时随时间变化改变它们的输出,却不破坏这条规则。
我有点分不清楚到底应该严格要求本身挤时间作,仍是随意些。这个问题得好好思考一下。