前端框架学习-React(一)

React 应用程序是由组件组成的。

  • react 程序是用的jsx语法,使用这种语法的代码需要由babel进行解析,解析成js代码。

    jsx语法:

    1. 只能返回一个根元素

    2. 所有的标签都必须闭合(自闭和或使用一对标签的方式闭合)

    3. 使用驼峰式命名法给大部分属性命名如:className

    4. 大写字母开头的标签一般都是组件

    5. jsx标签的属性,使用引号传递字符串,使用一组{和}传递js变量,且大括号中可以写js的表达式,也可以传递使用个另外一对额外的大括号包裹对象。

    6. 标签中可以使用三目运算符

      在 JSX 中,{cond ? <A /> : <B />} 表示 "当 cond 为真值时, 渲染 <A />,否则 <B />"

      在 JSX 中,{cond && <A />} 表示 "当 cond 为真值时, 渲染 <A />,否则不进行渲染"。

      js 复制代码
      return (
        <li className="item">
          {isPacked ? name + ' ✔' : name}
        </li>
      );
    7. 渲染列表:使用map()方法生成一组相似组件,使用filter()方法来筛选数组

      js 复制代码
      const listItems = chemists.map(person =>
        <li>...</li> // 隐式地返回!
      );
         
      const listItems = chemists.map(person => { // 花括号
        return <li>...</li>;
      });
  • 组件引入语法用到了ES6的模块化编程语法

    1. 解构赋值语法:可以将数组中的值或对象的属性取出,赋值给其他变量。

    2. 展开运算符:

      js 复制代码
      function Profile({ person, size, isSepia, thickBorder }) {
        return (
          <div className="card">
            <Avatar
              person={person}
              size={size}
              isSepia={isSepia}
              thickBorder={thickBorder}
            />
          </div>
        );
      }
      {/* 关于Avatar那一部分可以写成 */}
      <Avatar {...props} />
  • React 三大元素:

    • State对象(要将state视为只读的)

      在数据发生改变之后页面上的内容才会重新渲染、

      • 设置 state 不会更改现有渲染中的变量,会请求一次新的渲染。
      • React 将 state 存储在组件之外,就像在架子上一样。
      • 当你调用 useState 时,React 会为你提供该次渲染 的一张 state 快照。

      更新state对象时要传递一个新的值,即使时一个json对象。

      • 你可以使用这样的 {...obj, something: 'newValue'} 对象展开语法来创建对象的拷贝。

      更新state中的数组:

      推荐使用(会返回一个新数组)
      添加元素 concat,...arr
      删除元素 filter,slice
      替换元素 map
      排序 先将数组复制一份儿

      可以使用 Immer 来保持代码简洁。

      相同UI树上的元素的State将会被保留,位置不同的组件会使state重置

      • 你可以通过为一个子树指定一个不同的 key 来重置它的 state。
    • props对象

      在标签上添加属性,即可给组件添加prop属性。在子组件中可以通过props读取到对应的属性,解构赋值时可以给一个默认值

      javascript 复制代码
      function Avatar({ person, size = 100 }) {
        // ...
      }

      组件间共享状态:可以通过状态提升的方式,让后再通过props传递给子组件。

      通过context上下文传递参数

      1. 创建context

        js 复制代码
        import { createContext } from 'react';
        export const LevelContext = createContext(1);
      2. 使用context

        js 复制代码
        {/* 组件会使用 UI 树中在它上层最近的那个 <LevelContext.Provider> 传递过来的值。 */}
        import { LevelContext } from './LevelContext.js';
        const level = useContext(LevelContext);
      3. 提供context

        js 复制代码
        {/* 在父组件中设定对应的值 */}
        <section className="section">
            <LevelContext.Provider value={level}>
          		{children}
            </LevelContext.Provider>
        </section>
    • ref对象

  • React的交互:

    • 给元素的事件传递一个函数,而调用一个函数。

      js 复制代码
      <button onClick={handleClick}> {/* 正确 */}
      <button onClick={handleClick()}>{/* 错误 */}
  • 在 React 中,useState 以及任何其他以"use"开头的函数都被称为 Hook。

    • 使用useImmerReducer可以将通知同一个state的方法,组织到一起。提高代码的可读性。

      • 把useState转化为useReducer:
        1. 通过事件处理函数 dispatch actions;
        2. 编写一个 reducer 函数,它接受传入的 state 和一个 action,并返回一个新的 state;
        3. 使用 useReducer 替换 useState;
      js 复制代码
      import { useImmerReducer } from 'use-immer';
      import AddTask from './AddTask.js';
      import TaskList from './TaskList.js';
      
      function tasksReducer(draft, action) {
        switch (action.type) {
          case 'changed': {
            const index = draft.findIndex((t) => t.id === action.task.id);
            draft[index] = action.task;
            break;
          }
          case 'deleted': {
            return draft.filter((t) => t.id !== action.id);
          }
          default: {
            throw Error('未知 action:' + action.type);
          }
        }
      }
      
      export default function TaskApp() {
        const [tasks, dispatch] = useImmerReducer(tasksReducer, initialTasks);
        function handleChangeTask(task) {
          dispatch({
            type: 'changed',
            task: task,
          });
        }
        function handleDeleteTask(taskId) {
          dispatch({
            type: 'deleted',
            id: taskId,
          });
        }
        return (
          <>
            <h1>布拉格的行程安排</h1>
            <AddTask onAddTask={handleAddTask} />
            <TaskList
              tasks={tasks}
              onChangeTask={handleChangeTask}
              onDeleteTask={handleDeleteTask}
            />
          </>
        );
      }
      let nextId = 3;
      const initialTasks = [
        {id: 0, text: '参观卡夫卡博物馆', done: true},
        {id: 1, text: '看木偶戏', done: false},
        {id: 2, text: '打卡列侬墙', done: false},
      ];
相关推荐
随风一样自由9 分钟前
【React+TS71007】Next.js “use client” 误用导致 TS71007:客户端/服务端引入问题的完整排查与修复
前端·javascript·react.js
代码山河35 分钟前
键盘输入与输出:Scanner与System.out详解
java·学习·架构·教程·面向对象·项目
一楼的猫38 分钟前
活动会议照片直播云相册:服务形式与适用场景
学习
愤怒火龙果44 分钟前
AIGC 安全学习笔记02 后门攻击・LLM 安全靶场・提示词注入
学习·安全·aigc
kkkkkkkkkk_Z1 小时前
新手自学嵌入式 | 学习日记: Linux驱动进阶 —— Platform总线与I2C子系统实战
linux·运维·学习
外收内放1 小时前
FastAPI猜字谜实战(3):把每一局存成JSON
开发语言·python·学习·json·fastapi
Yurko132 小时前
原码、反码、补码的快速学习
笔记·学习·其他
tellmewhoisi3 小时前
深度学习8:神经网络学习5:随机梯度下降法(基本概念,基本原理)
深度学习·神经网络·学习
Canmag 兴隆磁性12 小时前
中大型钕铁硼产品的磁通测量与自动分选:一条产线自动化的工程实现思路
运维·学习·自动化·永磁材料
小黄人软件14 小时前
桌面需要整理吗?有工具自动分类
学习