05_组件&Props

// 组件允许你将 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 不被更改

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值