React-实习期笔记

React

简介:

React 是一个用于构建用户界面的 JAVASCRIPT 库。

  • 声明式设计 −React采用声明范式,可以轻松描述应用。
  • 高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。
  • 灵活 −React可以与已知的库或框架很好地配合。
  • JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。
  • 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
  • 单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。

JSX:

  • React 并没有采用将标记与逻辑进行分离到不同文件这种人为地分离方式,而是通过将二者共同存放在称之为“组件”的松散耦合单元之中,来实现关注点分离。

嵌入表达式

大括号可以是各种js表达式如:1+1,user.nickName,getName(user)

const name = 'Josh Perez';
const element = <h1> Hello, {name} </h1>;
const element = <h1> Hi, {getName(user)} </h1>;

指定属性

你可以通过使用引号,来将属性值指定为字符串字面量:

const element = <a href="https://www.reactjs.org"> link </a>;

也可以使用大括号,来在属性值中插入一个 JavaScript 表达式:

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

但是注意不能同时使用{}“”

防止注入攻击

React DOM 在渲染所有输入内容之前,默认会进行转义。

const title = response.potentiallyMaliciousInput;
// 直接使用是安全的:
const element = <h1>{title}</h1>;

元素渲染

  • 元素是构成React应用的最小砖块

  • 将元素渲染为DOM

    将元素传入render,能够将其渲染到对应的根DOM节点下

    const element = <h1>Hello, world</h1>;
    ReactDOM.render(element, document.getElementById('root'));
    
  • 更新已渲染元素

    React元素是不可变对象,一旦被创建,就无法更改它的子元素或者属性,它表示了某个时刻的UI

    // 计时器例子
    function time() {
      const element =(
        <div>
          <p>The Time Is {new Date().toLocaleTimeString()}</p>
        </div>
      );
      ReactDOM.render(
        element,
        document.getElementById('clock')
      )
    }
    // setInterval() 方法会不停地调用函数(按照指定周期),直到 clearInterval() 被调用或窗口被关闭。
    // 这里表示每1000ms调用一次tick函数
    setInterval(tick, 1000);
    

    image-20220224143424989

    虽然每次都新建了整个div,但是只有不要变化的位置被刷新了

组件&Props

  • 函数组件

  • class组件

  • 父组件可以向传递props

  • 提取可复用的组件,组成复杂组件

  • props只读,在任何时候都不能被修改

  • 详见Demo

  • 生命周期方法

    • 装载-componentDidMount()
    • 卸载-componentWillUnmount()
    • 下图来优化上文的时间,用class组件完成,详细描述了组件实例被创建并插入到DOM的生命周期调用顺序

    image-20220224154912911

  • 关于State

    1. 不能直接修改State,使用setState
    2. this.propsthis.state 可能会异步更新,所以不要依赖他们的值来更新下一个状态。
    3. State的更新会被合并,state的成员可以单独被更新,react会将他们

数据向下流动

  • 不管是父组件或是子组件都无法知道某个组件是有状态的还是无状态的,并且它们也并不关心它是函数组件还是 class 组件。
  • state是局部的、封装的。除了拥有和设置他的组件,其他组件都无法访问
  • 组件可以将他的state作为props向下传递到子组件中,但子组件也不会知道props的来源是怎样的

事件处理

  • 小驼峰命名
  • 传入函数作为事件,而不是字符串

image-20220224161953100

  • 不能返回false的方式阻止默认行为,而是使用preventDefault
  • 回调函数问题见补充

条件渲染

  1. 简单条件

image-20220224171645068

  1. 双目运算符

    • true && expression总是会返回expression, 而false && expression总是会返回false(即跳过后面的内容不渲染)

      <!--count不为空的时候才会显示<h1>标签-->
      <div>
            { count && <h1>Messages: {count}</h1>}   
      </div>
      
  2. 三目运算符

    • condition ? true : false
    • 没啥好举例的同上
  3. 阻止组件渲染

    • return null或者return;来阻止组件渲染(Demo中的落子函数handleClick有体现)

列表和key

  • map和key的应用在Demo中体现的挺好的(感觉结合例子更好理解),这里提取几点注意
  1. 元素的 key 只有放在就近的数组上下文中才有意义。
  2. key在兄弟节点之间必须唯一
  3. 提取key基本是必须的,如果提取不了key,可能数据结构就有问题

表单

  • 受控组件

    在 React 中,可变状态(mutable state)通常保存在组件的 state 属性中,并且只能通过使用 setState()来更新。

    渲染表单的 React 组件控制着用户输入过程中表单发生的操作。被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”。

    image-20220225104132442

组合

  • React 有十分强大的组合模式。推荐使用组合而非继承来实现组件间的代码重用。

  • 通过JSX嵌套,将任意组件传递给子组件

    image-20220225111033003

    image-20220225111202590

  • 特殊与一般

    image-20220225111533169

  • 继承

    Facebook官方建议:

    • 在 Facebook,我们在成百上千个组件中使用 React。我们并没有发现需要使用继承来构建组件层次的情况。

    • Props 和组合为你提供了清晰而安全地定制组件外观和行为的灵活方式。注意:组件可以接受任意 props,包括基本数据类型,React 元素以及函数。

生命周期

  • 挂载和卸载-(见’组件&Props‘中有详细过程)

    • constructor(): 在 React 组件挂载之前,会调用它的构造函数。
    • getDerivedStateFromProps(): 在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。
    • render(): render() 方法是 class 组件中唯一必须实现的方法。
    • componentDidMount(): 在组件挂载后(插入 DOM 树中)立即调用。
  • 更新

    • getDerivedStateFromProps(): 在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。根据 shouldComponentUpdate() 的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。
    • shouldComponentUpdate():当 props 或 state 发生变化时,shouldComponentUpdate() 会在渲染执行之前被调用。
    • render(): render() 方法是 class 组件中唯一必须实现的方法。
    • getSnapshotBeforeUpdate(): 在最近一次渲染输出(提交到 DOM 节点)之前调用。
    • componentDidUpdate(): 在更新后会被立即调用。

官方Demo

初始文件结构:

image-20220224103354640

https://zh-hans.reactjs.org/

  1. 传递React参数

    在 React 应用中,数据通过 props(propertis)的传递,从父组件流向子组件。

    image-20220223104443159

    image-20220223104607335

  2. 添加交互

    image-20220223111404488

    image-20220223111443711

    1. 使用数组存储棋盘

      选择使用一个长度为9的数组来保存棋盘的状态,又Board来维护,并由Board来将此数组传递给子组件Square

      image-20220223114725956

      image-20220223114915829

      • 到此, Square 组件不再持有 state,因此每次它们被点击的时候,会从父组件接收值,并通知父组件。在 React 术语中,我们把目前的 Square 组件称做“受控组件”。在这种情况下,Board 组件完全控制了 Square 组件。

      • 调用了 .slice() 方法创建了 squares 数组的一个副本,而不是直接在现有的数组上进行修改。涉及到了React的不变性。

        不变性,不直接修改而是使用新数据代替旧数据的好处;

        1. 简化复杂功能
        2. 跟踪数据的改变
        3. 确定在React中何时重新渲染
      • 函数组件

        image-20220223142325460

      • 状态提升

        当你遇到需要同时获取多个子组件数据,或者两个组件之间需要相互通讯的情况时,需要把子组件的 state 数据提升至其最近的共同的父组件当中保存。之后父组件可以通过 props 将状态数据传递到子组件当中。这样应用当中所有组件的状态数据就能够更方便地同步共享了。

    2. 轮流落子并判断输赢

      • 维护一个布尔值判断落子者
      • 写一个判断输赢的函数,在落子前进行判断,如果已经决出胜负就不能再落子了

      image-20220223145114077

    3. 保存历史记录

      • 使用一个history数组保存每次更新的棋盘
      • 提升状态,将棋盘的所有信息(落子者、历史信息、落子处理)从Board移到其父组件Game

      image-20220223174407736

    4. 实现时间回退和前进

      • 实现页面显示历史列表

      image-20220224095436358

      • 棋盘处理

        image-20220224101158141

      • 落子处理

        image-20220224101649038

补充:

  1. slice()

    语法:array.slice(start, end)

    参数:

    start:从何处开始截取,负数表示倒数第几个

    end:从何处结束截取,负数表示倒数第几个

    只有一个参数:从第几个截取到最后

    slice() 方法可从已有的数组中返回选定的元素。

    slice() 方法可提取字符串的某个部分,并以新的字符串返回被提取的部分。

    注意: slice() 方法不会改变原始数组。

  2. map()

    在 JavaScript 中,数组拥有 map() 方法,该方法通常用于把某数组映射为另一个数组

    image-20220224101141781

  3. concat()

    concat() 方法用于连接两个或多个数组。

    concat() 方法不会更改现有数组,而是返回一个新数组,其中包含已连接数组的值。

补充

  1. 回调函数要手动绑定this

    image-20220224163512888

    或者用Demo中的解决方法,用箭头函数去解除this带来的歧义

    image-20220224163710979

    但这种写法的问题也有可能带来性能问题,官方说法如下:

    此语法问题在于每次渲染时都会创建不同的回调函数。在大多数情况下,这没什么问题,但如果该回调函数作为 prop 传入子组件时,这些组件可能会进行额外的重新渲染。我们通常建议在构造器中绑定或使用 class fields 语法来避免这类性能问题

  2. 组件中的html语法

    • 与传统html不同的是,class要改写成className
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: React-saga和React-thunk都是用于处理异步操作的中间件。 React-thunk是Redux官方推荐的中间件之一,它允许我们在Redux中编写异步操作,使得我们可以在Redux中处理异步操作,而不需要在组件中处理异步操作。Thunk是一个函数,它接收dispatch和getState作为参数,并返回一个函数,这个函数接收dispatch作为参数,并在异步操作完成后调用dispatch。 React-saga是另一个处理异步操作的中间件,它使用了ES6的Generator函数来处理异步操作。Saga使用了一种称为Effect的概念,它是一个简单的JavaScript对象,用于描述异步操作。Saga使用了一种称为yield的语法,它允许我们在Generator函数中暂停异步操作,并在异步操作完成后继续执行。 总的来说,React-thunk和React-saga都是用于处理异步操作的中间件,它们的实现方式不同,但都可以让我们在Redux中处理异步操作。选择哪种中间件取决于个人的喜好和项目的需求。 ### 回答2: React-Saga和React-Thunk都是React应用中用于处理异步操作的中间件。它们的主要目的是在Redux应用中,帮助我们管理异步操作。这两个中间件都可以让React应用更加的灵活、健壮和易于维护。 React-Saga的核心理念是利用生成器函数来处理异步操作,Saga通过使用生成器来让异步操作变得像同步操作一样,其中每个异步操作都会被转化为一个迭代器函数,这些函数可以被Saga调用和暂停。 Saga主要有以下几个特点: 1. Saga可以使异步操作更加同步和简单,让异步调用变得更容易。Saga使用了轻量级、高效的生成器函数,从而有效地减少了异步调用中的代码复杂度。 2. Saga可以很好地管理和协调多个异步操作。Saga可以在任意阶段暂停异步操作,等待其他异步操作完成之后再继续执行。 3. Saga可以捕获和控制异步操作的错误、超时和状态。当出现问题时,Saga可以修复错误或者更改异步操作的状态,保证应用程序的稳定性和可靠性。 React-Thunk的核心概念是利用闭包函数来处理异步操作,Thunk将异步操作转化为一个闭包函数,然后通过回调函数将其传递到Redux的异步流中。 Thunk的主要特点有以下几个: 1. Thunk可以轻松处理异步操作,没有复杂的代码逻辑或者概念。 2. Thunk主要使用了闭包函数来捕捉当前异步操作的上下文,使得处理异步操作更加的简单、方便和自然。 3. Thunk可以轻松控制异步操作的状态、结果和错误处理,保证应用程序的稳定性和可靠性。 总之,React-Saga和React-Thunk都是帮助我们管理和处理应用程序的异步操作的中间件。它们都有自己独特的实现方式和特点。我们可以根据自己的项目需求和开发团队的技能水平来选择适合我们的中间件。 ### 回答3: React-saga 和 React-thunk 都是针对 React 应用中异步操作的中间件。它们两个都可以用来控制异步流程,使得我们可以更好的管理 React 应用程序中异步操作的数据和状态。 相较于 react-thunk, react-saga 是一个更加强大的中间件,它基于 generator 函数的概念,可以用来控制非常复杂的异步流程,使得我们可以在操作时更加精细地掌控多个异步操作的执行顺序和状态。 如果说 react-thunk 的核心概念是将异步操作封装进一个函数里,而在需要时调用这个函数即可,那么 redux-saga 的核心概念则是分离出一个独立的 Generator 函数来代表所有的异步业务逻辑。 redux-saga 可以让你从另一个角度处理异步流程,使你能够同步处理异步操作,不同的 Saga 可以用一种集中且易于理解的方式组合起来,组成它们自己的执行序列。 总而言之,React-saga和React-thunk 都是 React 应用程序开发中非常实用的工具,对于管理异步操作和数据状态非常有帮助。但是针对不同的开发需求,我们需要选择相应的中间件,来实现我们最好的业务逻辑。所以我们在使用的时候需要根据实际情况选择适合的中间件进行操作,以达到最好的效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值