react 初步学习

 什么是 React ?

  React是一个声明式的,高效的,并且灵活的用于构建用户界面的 JavaScript 库

  一个最简单的React例子

ReactDom.render(
    <h1>Hello World</h1>,
    document.getElementById('root')
)

ReactDom.render接受两个参数,第一个是要被插入的内容,第二个是插入到DOM或者说index.html的位置

一个与Html对比的简单组件

  如下是一个 React 组件

class ShoppingList extends React.Componnet {
    render() {
        return (
            <div className="shopping-list">
                <h1>Shoping List for {this.props.name}</h1>
                <ul>
                    <li>Instagram</li>
                    <li>WhatApp</li>
                    <li>Oculus</li>
                </ul>
            </div>
        )
    }
}

// Example usage:  <ShoppingList name="Mark" />

  在这里,ShoppingList是一个 React组件类,或 React组件类型。组件接受参数,称为属性 props, 并通过 render方法返回一个现实的视图层次结构。

render 方法返回您要渲染的内容描述,然后React接受该描述并将其渲染到屏幕上,特别是,render 返回一个React 元素,这是一个渲染内容的轻量级的描述。大多数
React 开发人员使用 JSX 语法,也是上述案例写到的语法。

JSX 语法的转换规则为: <div /> 语法在构建是被转换为 React.createElement('div')。因此,上面的例子等价于:

return React.createElement('div', {className: 'shopping-list'},
    React.createElement('h1', /* h1 children ... */),
    React.createElement('ul', /* ul children ... */)
);

  既然 JSX 在 React 开发者中这么流行,那 JSX 又是什么呢?

 JSX 语法

JSX 它是 Javascript 的一种拓展语法,能够让你的 Javascript 中和正常描述 HTML一样编写 HTML。

  你可以用 花括号 将任意 Javascript 表达式嵌入到 JSX 中。例如:表达式 1 + 2, 变量 user.firstName, 和函数 formatName(User) 等都可以嵌入使用

function formatName(user) {
    return user.firstName + ' ' + user.lastName;
}

const user = {
    firstName: 'harper',
    lastName: 'Perez'
}

const element = {
    <h1> Hello, {formatName(user)}! </h1>
}

ReactDOM.render (
    element,
    document.getElementById('root')
)

  请注意,为了方便阅读开发者们常将 JSX分割成多行包裹起来,因为这可以避免分号自动插入的陷阱,如

{ 1
2 } 3
// is transformed to
{ 1
;2 ;} 3;

JSX 也是一个表达式

  编译之后, JSX 表达式也就成了一个常规的 javascript 对象

  也正因为如此,我们可以在 if 语句或这是 for 循环语句中使用 JSX,用它给变量赋值,当做参数接受,或者作为函数的返回值

function getGreeting(user) {
    if (user) {
        return <h1>Hello. {formatName(User}</h1>;
    }
    return <h1>Hello, Stranger</h1>
}

用 JSX 指定属性值

  你可以用花括号嵌入一个 JavaScript 表达式作为属性值

// 用引号形式
const element = <div tableIndex="0"></div>;
// 用表达式,并且表达式用花括号包裹
const element = <img src={user.avatarUrl}></img>;

用 JSX 指定子元素

  如果是空标签,可以直接用 /> 闭合

const element = <img src={user.avatarUrl} />

  如果包含子标签:

<div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
</div>

比起 HTMLJSX 更接近于Javascript,所以React DOM规范使用驼峰(camelCase)属性命名约定,而不是HTML属性名称,当然,html的部分属性名称也作为保留字,不可使用,例如 class
因此,class 在 JSX 中 变为 className, tableindex 变为 tableIndex

元素渲染到DOM

  正常情况下,你的 index.html 文件下会有这么一个div

<div id='root'></div>

  这个root DOM 节点挂在所有React DOM的位置。正常情况下,对于一个React单页面应用构建,只需要一个单独的根DOM节点即可。但如果要把React整合到现有的APP中,则可能会使用到多个DOM节点。

  React利用render方法将React元素渲染到DOM上,一旦元素被渲染到页面了之后,就不能在修改器子元素或任何元素的属性,就像电影里的一帧,在某以特定的时间点的UI效果,那元素的更新呢?没错,就是重新 render

function tick() {
    cosnt element = {
        <div>
            <h1>Hello, world</h1>
            <h2>It is {new Date().toLocaleTimeString()}.</h2>
        </div>
    };
    ReactDom.render (
        element,
        document.getElementById('root')
    )
}

setInterval(tick, 1000);

实际上,大多数 React 应用只会调用一次ReactDom.render(),而实现组件更新的办法就是将代码封装在有状态的组件中。

React 只更新必须更新的部分

  这正是 React 的强大之处。React DOM 会将元素及其子元素与之前版本逐一对比,并只对有必要更新的 DOM 进行更新, 以达到 DOM 所需的状态。

  开发过程中,更应该每个时间点UI的表现, 而不是关注随着时间不断更新UI的状态, 可以减少很多奇怪的 bug

组件和属性

  组件 components 和属性 props,其中,属性是单词 property 的代码简写。

定义组件的两种办法

  定义组件有两种方式

  1. 函数式组件定义
  2. 类组件定义
      最简单的定义组件的方法就是写一个 Javascript 函数

function Welcome(props)  {
    return <h1>Hello, props.name</h1>
}

  这就是一个有效的组件,它接首了一个 props 参数,并返回了一个React元素,这是一个函数式组件,表面上看,他就是一个 Javascript函数。

  类组件的定义则依赖ES6 的 class 来定义,下面这种定义方法和上方是等效的;

class Welcome extends React.Component {
    render() {
        return <h1>Hello, {this.props.name}</h1>;
    }
}

渲染一个组件

// DOM标签作为组件
const element = <div />;
// React 元素作为组件
const element = <Welcome name="Sara" />;

  当React 遇到一个代表用户定义组件的元素时,它将 JSX 属性以一个单独对象即
props对象 的形式传递给相应的组件,例如

function Welcome(props) {
    return <h1>Hello, {props.mname] </h1>;
}
const element = <Wlecome name="Sara" />;
ReactDOM.render(
    element,
    document.getElementById('root')
)

理解

  1. 调用 ReactDOM.render() 方法并向其传入了<Welcome name="Sara" />元素
  2. Raect 调用 Welcome 组件,并向其传入了 {name: ‘Sara’} 作为 props对象
  3. Welcome 组件返回 <h1>Hello, Sara</h1>
  4. React DOM 迅速更新 DOM,使其显示为 <h1>Hello, Sara</h1>

组件名称总是以大写字母开始, 如本例子中 <Welcome />, 而不是 <welcome />

构成组件

  既然组件是单独的一个React元素,那他能单独工作,因此我们能在一个React 元素中多次引用到相同的组件, 举个例子:

function Welcome(props) {
    return <h1>Hello, {props.name}</h1>
}
function App() {
    return (
        <Welcome name="Sara" />
        <Welcome name="Lucy" />
        <Welcome name="Edite" />
    )
}

ReactDOM.render(
    <App />,
    document.getElementBuId('root')
)

  通常情况下, React apps 都有一个单独的顶层的 App 组件。如果是在已有的应用中整合React,也需要由下至上的从小的组件开始逐步整合到视图顶层的组件中。

组件必须返回一个单独的根元素,这就是为什么我们要添加一个 <div>来包裹所有的<Welcome /> 元素的原因

提取组件

  对于一个React 元素,如果其中含有可复用或可能会重复使用的内容,不要害怕把它单拿出来多个更小的组件。

  提取组件可能看起来是一个繁琐的工作,但是在大型的 App 中可以回报给我们的是大量的可复用组件。一个好的经验准则是如果你 UI 的一部分需要用多次 (ButtonPanelAvatar),或者本身足够复杂(AppFeedStoryComment),最好的做法是使其成为可复用组件。

Props 是只读的

  无论你用函数或类的方法来声明组件,

  虽然 React 很灵活,但是它有一条严格的规则:**所有 React 组件都必须是纯函数,并禁止修改其自身 props **。所谓的纯函数就是:传入函数参数不会在函数执行过程中发生改变,比如自增操作 a++

  如果props是只读的,那传递给子元素(子组件)的参数岂不是不能修改了?那子元素如何与父元素做交互呢?React还给我们提供了状态属性 state供我们在子组件内部修改值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值