抽离组件
永远不要害怕将组件拆分成更小的组件。
例如,考虑这个Comment
组件:
import React from 'react'; import ReactDOM from 'react-dom'; function formatDate(date) { return date.toISOString(); } 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"> {formatDate(props.date)} </div> </div> ); } ReactDOM.render( <Comment author={{ avatarUrl: 'https://ss0.bdstatic.com/7Ls0a8Sm1A5BphGlnYG/sys/portrait/item/3ae1dc06.jpg', name: 'zhangyatao' }} text={'我的名字叫张亚涛'} date={new Date()}/>, document.getElementById('root') );
它接受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"> {formatDate(props.date)} </div> </div> ); }
接下来,我们将提取一个UserInfo
组件,该组件在用户名称旁边呈现一个avatar
:
function UserInfo(props) {
return (
<div className="UserInfo">
<avatar uer={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"> {formatDate(props.date)} </div> </div> ); }
最终的代码如下:
import React from 'react'; import ReactDOM from 'react-dom'; function formatDate(date) { return date.toISOString(); } function Avatar(props) { return ( <img className="Avatar" src={props.user.avatarUrl} alt={props.user.name} /> ); } function UserInfo(props) { return ( <div className="UserInfo"> <Avatar user={props.user}/> <div className="UserInfo-name"> {props.user.name} </div> </div> ); } function Comment(props) { return ( <div className="Comment"> <UserInfo user={props.author}/> <div className="Comment-text"> {props.text} </div> <div className="Comment-date"> {formatDate(props.date)} </div> </div> ); } ReactDOM.render( <Comment author={{ avatarUrl: 'https://ss0.bdstatic.com/7Ls0a8Sm1A5BphGlnYG/sys/portrait/item/3ae1dc06.jpg', name: 'zhangyatao' }} text={'我的名字叫张亚涛'} date={new Date()}/>, document.getElementById('root') );
让一个个可重用组件在大型应用程序中交付使用的过程中,抽离组件起初可能看起来像又脏又累的活儿。 所以有一个好的经验法则:如果UI的一部分被使用了好几次(按钮,面板,头像),或者内部比较复杂的东西(App,FeedStory,评论),一个可重用的组件对它来说可以达到最大的发挥空间。