// 组件允许你将 UI 拆分为独立可复用的代码片段,并对每个片段进行独立构思。
// 组件,从概念上类似于 javascript 函数。它接受任意的入参(即 “props”),并返回用于描述页面展示内容的 React 元素。
// 函数组件与 class 组件
// 定义组件最简单的方式就是编写 javascript 函数:
function Welcome(props) {
return <h1>11111{props.name}</h1>
}
/* 该函数是一个有效对的 React 组件,因为它接收唯一带有数据的 “props” 对象与并返回一个 React 元素。
这类组件被称为 “函数组件”,因为它本质上就是 javascript 函数。
*/
// 你同时还可以使用 es6 的 class 来定义组件:
class Welcome extends RTCIceCandidate.component{
render(){
return <h1>22222,{this.props.name}</h1>
}
}
// 渲染组件:
// 之前,我们遇到的 React 元素只是 DOM 标签
const element = <div/>
// 不过React 元素也可以是用户自定义的组件:
const element = <Welcome name="ssss"/>
// 当 React 元素为用户自定义组件时,它会将 jsx 所接收的属性(attributes) 转换为单个对象传递给组件,这个对象被称之为 “props”
// 例如:这段代码会在页面上渲染“Hello,Sara”
function Welcome(props) {
return <h1>hello,{props.name}</h1>
}
const element = <Welcome name="Sara" />
ReactDOM.render(
element,
document.getElementById('root')
)
/* 以上例子中发生了:
1. 我们调用 ReactDOM.render() 函数,并传入 <Welcome name="Sara"> 作为参数
2. React 调用 Welcome 组件,并将 {name:'Sara'} 作为 Props 传入
3. Welcome 组件将 <h1>Hello,Sara</h1> 元素作为返回值
4. ReactDOM 将 DOM 高效地更新为 <h1>Hello,Sara</h1>
*/
// 注意:组件名称必须以大写字母开头。
// React 会将以小写字母开头的组件视为原生 DOM 标签。
// 组合组价:例如:我们可以创建一个可以多次渲染 Welcome 组件的 App 组件:
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) {
// props是组件调用者传入的所有属性 的 一个对象
/* ==> props: {
'author': {
'avatarUrl': null,
'name': null
},
'text': null,
'date': null
}
*/
return (
<div className="Comment">
<div className="UserInfo">
<img className="Avatar" src={props.author.avatarUrl} alt={props.author.name}></img>
<div className="UserInfo-name">{props.author.name}</div>
</div>
<div className="Comment-text">{props.text}</div>
<div className="Comment-date">{formatData(props.date)}</div>
</div>
)
}
// 该组件用于描述一个社交媒体网络上的评论功能,它接收 author(对象),text(字符串)以及 date(日期)作为 props.
// 该组件由于嵌套的关系,变的难以维护,且很难复用它的各个部分。因此,让我们从中提取一些组件出来。
// 首先,我们将提取 Avatar 组件: --------------------------------------------------------
function Avatar(props) {
return (
<img src={props.user.avatarUrl} alt={props.user.name}/>
)
}
// 简化 Comment
function Comment(props) {
// props是组件调用者传入的所有属性 的 一个对象
/* ==> props: {
'author': {
'avatarUrl': null,
'name': null
},
'text': null,
'date': null
}
*/
return (
<div className="Comment">
<div className="UserInfo">
{/* <img className="Avatar" src={props.author.avatarUrl} alt={props.author.name}></img> */}
<Avatar user={props.author}/>
<div className="UserInfo-name">{props.author.name}</div>
</div>
<div className="Comment-text">{props.text}</div>
<div className="Comment-date">{formatData(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) {
// props是组件调用者传入的所有属性 的 一个对象
/* ==> props: {
'author': {
'avatarUrl': null,
'name': null
},
'text': null,
'date': null
}
*/
return (
<div className="Comment">
<UserInfo user={props.author}/>
<div className="Comment-text">{props.text}</div>
<div className="Comment-date">{formatData(props.date)}</div>
</div>
)
}
/* 最初看上去,提取组件可能是一件繁重的工作,但是,在大型应用中,构建可复用组件是完全值得的。
根据经验来看,如果 UI 中有一部分被多次使用(Button, Panel, Avatar),或者组件本身就足够复杂(App, FeedStory, Comment),
那么它就是一个可复用组件的候选项。
*/
// props 的只读性
// 组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props 。来看下这个 sum 函数:
function sum(a, b) {
return a + b
}
// 这样的函数就被称为 “纯函数”,因为该函数不会尝试更改入参,且多次调用下相同的入参始终返回相同的结果
// 相反,下面这个函数则不是纯函数,因为它更改了自己的入参:
function withdraw(account, amount) {
account.total -= amount; // account.total = account.total - amount
}
// React 非常灵活,但它也有一个严格的规则:所有 React 组件都必须像纯函数一样保护它们的 props 不被更改
05_组件&Props
最新推荐文章于 2024-10-16 16:26:58 发布