React 组合组件运用
发布时间:2023-04-10 08:49:04 所属栏目:教程 来源:
导读:使用组件的目的就是通过构建模块化的组件,相互组合组件最后组装成一个复杂的应用。
在 React 组件中要包含其他组件作为子组件,只需要把组件当作一个 DOM 元素引入就可以了。
一个例子:一个显示用户头像的组
在 React 组件中要包含其他组件作为子组件,只需要把组件当作一个 DOM 元素引入就可以了。
一个例子:一个显示用户头像的组
使用组件的目的就是通过构建模块化的组件,相互组合组件最后组装成一个复杂的应用。 在 React 组件中要包含其他组件作为子组件,只需要把组件当作一个 DOM 元素引入就可以了。 一个例子:一个显示用户头像的组件 Avatar 包含两个子组件 ProfilePic 显示用户头像和 ProfileLink显示用户链接: import React from 'react'; import { render } from 'react-dom'; const ProfilePic = (props) => { return ( <img src={'http://graph.facebook.com/' + props.username + '/picture'} /> ); } const ProfileLink = (props) => { return ( <a href={'http://www.facebook.com/' + props.username}> {props.username} </a> ); } const Avatar = (props) => { return ( <div> <ProfilePic username={props.username} /> <ProfileLink username={props.username} /> </div> ); } render( <Avatar username="pwh" />, document.getElementById('example') ); 通过 props 传递值。 循环插入子元素 如果组件中包含通过循环插入的子元素,为了保证重新渲染 UI 的时候能够正确显示这些子元素,每个元素都需要通过一个特殊的 key 属性指定一个唯一值。具体原因见这里,为了内部 diff 的效率。 key 必须直接在循环中设置: const ListItemWrapper = (props) => <li>{props.data.text}</li>; const MyComponent = (props) => { return ( <ul> {props.results.map((result) => { return <ListItemWrapper key={result.id} data={result}/>; })} </ul> ); } 你也可以用一个 key 值作为属性,子元素作为属性值的对象字面量来显示子元素列表,虽然这种用法的场景有限,参见Keyed Fragments,但是在这种情况下要注意生成的子元素重新渲染后在 DOM 中显示的顺序问题。 实际上浏览器在遍历一个字面量对象的时候会保持顺序一致,除非存在属性值可以被转换成整数值,这种属性值会排序并放在其他属性之前被遍历到,所以为了防止这种情况发生,可以在构建这个字面量的时候在key 值前面加字符串前缀,比如: render() { var items = {}; this.props.results.forEach((result) => { // If result.id can look like a number (consider short hashes), then // object iteration order is not guaranteed. In this case, we add a prefix // to ensure the keys are strings. items['result-' + result.id] = <li>{result.text}</li>; }); return ( <ol> {items} </ol> ); } this.props.children 组件标签里面包含的子元素会通过 props.children 传递进来。 比如: React.render(<Parent><Child /></Parent>, document.body); React.render(<Parent><span>hello</span>{'world'}</Parent>, document.body); HTML 元素会作为 React 组件对象、JS 表达式结果是一个文字节点,都会存入 Parent 组件的 props.children。 一般来说,可以直接将这个属性作为父组件的子元素 render: const Parent = (props) => <div>{props.children}</div>; props.children 通常是一个组件对象的数组,但是当只有一个子元素的时候,props.children 将是这个唯一的子元素,而不是数组了。 React.Children 提供了额外的方法方便操作这个属性。 提取组件 将组件拆分为更小的组件。 例如,参考如下 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"> {formatDate(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 组件内部是如何渲染的。因此,我们给它的 props 起了一个更通用的名字: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 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"> {formatDate(props.date)} </div> </div> ); } 最初看上去,提取组件可能是一件繁重的工作,但是,在大型应用中,构建可复用组件库是完全值得的。根据经验来看,如果 UI 中有一部分被多次使用(Button,Panel,Avatar),或者组件本身就足够复杂(App,FeedStory,Comment),那么它就是一个可复用组件的候选项。 (编辑:汽车网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |