01- react脚手架、jsx语法、组件、遍历、条件渲染、组件内外传值

笔记批注:易错 参考文献 重点 面试题

01 脚手架的使用

01.01 cra(create-react-app)使用;

  • vue的脚手架:vite -- 给vue3主要使用。
  • react的脚手架:create-react-app;
    • 创建一个react应用;create react app
    • 创建项目:npx create-react-app myappname
    • 初始化,启动项目:yarn installyarn start

参考文献:https://zh-hans.react.dev/learn/creating-a-react-app
cnpm、yarn、npx、pnpm命令都可以使用;
cra脚手架强制最新的版本,
node版本: 18.x+

01.02 项目目录 以及eject 解析

  • 文件:package.json项目配置 与package-lock.json 锁定:有新的版本或者依赖有问题,就锁定在固定的版本,项目如果跑不起来,可以尝试删除;

    • react-script 脚手架集成,包较大,基于webPack;
  • public文件夹:

    • 静态目录,项目入口页面 -- SPA单页应用入口页面;

    • index.html, icon偏好图标。(其他可以删除)

    • 禁止强制缩放代码添加,删除多余的代码
      <!DOCTYPE html>
      <html lang="zh">
      <head>
      <meta charset="UTF-8">
      <link rel="icon" href="/favicon.ico">
      <title>欢迎</title>
      <meta name="viewport" content="width=device-width, initial-scale=1, user-scalabel=no">
      </head>
      <body> 
        <div id="root"></div>
      </body>
      </html>
      
  • src文件夹:全部清空

    • 添加index.js
        // 主框架
        import React from "react"
        // 导入创建根节点方法,管理虚拟dom,真实dom挂载方法;
        import ReactDom from "react-dom/client"
        // 
        const root = ReactDom.createRoot(document.querySelector('#root'));
      
        // 调用render方法把虚拟节点渲染到容器上;(vue h函数)
        const VNode2 = <h1>好好学习</h1>
        const VNode = React.createElement(
        'h1',
          {
          style: {
            color: 'red'
                  },
          },
          "标题",
          React.createElement(
           'span',
             {
              style: {
                fontSize: '20px',
                color: 'green'
               }
              },
              "内容"
          )
        )
         // react 没有vue的template,script,style进行模块化管理;
         // 开发jsx语法
        root.render(
          VNode
        )
      
    • 项目源码;

可不用脚手架,把脚手架的依赖底层源码全部释放, 不可逆 -- npm run eject;

02 react 基础知识

02.01 react开发特性;

  • 每个react组件首行引入react框架;
  • react所有数据流皆单向,区别于vue双向绑定;
  • 一些皆组件,一个组件一个元素;
  • jsx (javaScript xml)--使用js和xml格式来编写页面;
    • jsx 中每一个html 片段都是js对象;

    • jsx语法片段被编译成createElement方法,类似vue的template;

    • 定义变量,方法( 函数组件
      // 01. 全局变量;
      const userName = '张三';
      const VNode = <h1>好好学习</h1>
      // 02. 闭包构成局部变量;
      function VNode() {
        const userName2 = "张三"  
        return (
          <h1>好好学习</h1>
        )
      }
      // 03,调用VNode方法(实际上就是一个组件),调用render方法把虚拟节点渲染到容器上;
       root.render(
        // VNode()
       // 03.01 首字母必须大写:错误:vNode, v-Node, vnode;
        <VNode/> 
        )
      
    • 类组件
      // 1.类组件定义: 定义普通类,继承Component类;
      // 2.继承:继承Component类,就必须实现Component类的固定方法 -- render
      class VNode extends React.Component{
                render() {
                  return (
              <h2>好好学习</h2>  
          ) 
        }
      }
      
    • 类组件-抽取组件
      // 1. 抽取组件;
      // 1.1 .js或.jsx 作为后缀(没区别)
      import React from "react";
      class VNode extends React.Component {
          render() {
              return {
                <h2>好好学习,天天向上 </h2>
              }
          }
      }
      export default VNode;
      // 2. 引入类组件;(导入组件位置一律置顶)
      import VNode from "./VNode"
      
  1. vue的组合式抄袭react的函数组件;
  2. react 16.8之前没有函数式编程,只有类组件
  3. 遵守es6模块华规则,导出定义组件;

03 条件渲染

03.01 元素条件渲染\样式绑定;

  1. 条件渲染:

    1. 元素各条件渲染
    2. 动态类名;
    3. 动态样式 classnames;
  2. 遍历渲染

    1. map方法;
    2. key的作用;
  • index.js--代码
      import React from "react"
      import {createRoot} from "react-dom/client"
      import Todos from "./Todos"
      
      createRoot('root').render(<Todos/>)    
    
    
  • Todos.jsx--代码
      import React, {Component} from "react";
      // 05 - 样式的引用;
      import './index.css'
       class Todos extends Component {
        render() {
            let data = Array(8).fill("").map((_,i) => ({id:'id-'+i, title:"今日任务开发", state:Math.random()> .5? '完成':"新建"
    }));
        let tr = (
            <tr key="1">
              <td></td><td></td><td></td>
            </tr>
        )    
        let trs =[tr];
        let finish = <button>完成</button>
        let active = <button>激活</button>
        // 04. map返回的是对象,因此可以直接返回
        let trs2 = data.map(item => {
                   return  (
                    <tr key={item.id}>
                      <td>{item.title}</td><td>{item.id}</td><td className="state-cls red">{item.state === '完成' ? finish : active}</td>
        // 06 - 样式的绑定数据,react 的className只接受一个字符串;
                      <td className={"state-cls red"}>{it.state === "完成"? <button>完成</button> : <button>激活</button>}</td>
                      <td className={it.state === "完成"? "state-cls":"state-cls new"}>it.state</td>
                // 07 - 样式的绑定,react安装第三方库代替三目运算;
                      <td className={classNames({"state-cls":true, "new":it.state === '新建'})}> </td>
                    </tr>
                )  
        })
    
            return {
            // 01. class 在react中是一个关键字,jsx也是js对象,所以样式名class不能写class,替换为className;
            <table className="table">
              <thead>
                <tr>
                    <td></td><td></td>
                </tr>
              </thead>
              <tbody>
                <tr>
                    <td></td><td></td>
                </tr>
               
              // 02. jsx中绑定任何属性数据,语法:{}
                {tr} 
              // 03. 如果绑定的是一个数组,那么数组中的jsx对象,必须有一个key属性。
                {trs}
              </tbody>
            </table>
            }
          }
        }
    
  // 1- 安装命令;
  // yarn add classnames;
  // 2- index.css样式
      .state-cls {
        font-size: 14px;
        color: green;
        };
      .red {
       color: red;
      };
      .new {
        color: orange;
      };
  1. class 在react中是一个关键字,jsx也是js对象,所以样式名class不能写class,替换为className;
  2. 绑定数组时,必须有一个key属性,key属性在diff算法中的唯一标识;没有key时,数据发生变化时,虚拟dom需要将对象逐个对比查找更新的属性;有key时,可以快速定位到哪个虚拟dom发生变化
  3. className库-参考文献:npmjs.com/package/classnames

03.02 事件、表单、state数据(组件内部数据)

  1. 表单绑定事件;
    1. 事件绑定和this指向;
    2. 表单功能实现value和onChange;
  2. state数据;
    1. state及特点;
    2. state定义和使用方法;
    3. setState方法及特性
  • MyForm.jsx
    import React from "react"
    class MyForm extends React.Component {
        count = 10
        // 04 - this 丢失;
        inputEvt(evt){
          console.log(arguments, evt.target.value)
          console.log(this);
        }
        // 04.1 - this获取,通过箭头函数找回;
        inputEvt = () => {
          console.log(evt.target.value);
          console.log(this)
          this.count = evt.target.value; // 将输入的值回显给表单变量;
        }
        // 04.2 - this获取2,使用call,apply,bind方法;
        getData(evt){
          console.log("结果",this.state.count)
        }
    render(){
      return (
        // 01 - react 和vue2一样,顶层元素只能有一个;
        <div>
          <input type="text" placeholder="请输入数据">
        </div>
        <hr/>
        <button>获取数据</button>
        // 01.2 - 修改后;
        <>
            <div>
         // 03 - 给表单提供一个value属性,没有onChange事件handler,它会被渲染成一个只读属性;
              <input type="text" placeholder="请输入数据" value={this.count} onChange={this.inputEvt}>
            </div>
            <hr />
         // 02 - react中绑定事件,{},所有的react的事件都是组合事件 -- react框架把原生事件进行了一个二次封装;
            <button onChange={this.getData}>获取数据</button>
         // 04.2.1  this获取2,使用call,apply,bind方法
            <button onChange={this.getData.bind(this)}>获取数据</button>
        <> 
      )
      }
    }
    export default MyForm
    
  • MyForm.jsx定义数据修改版
    import React from "react"
    class MyForm extends React.Component {
     // 05 - state名称固定不能变,类似vue的data,并且这个state数据为只读;
        state = {
          count : 10,
          
        }
        getData(){
          console.log(arguments)
    
        }
        // 04 - this 丢失;
        inputEvt(evt){
          console.log(arguments, evt.target.value)
          console.log(this);
        }
        // 04.1 - this获取,通过箭头函数找回;
        inputEvt = () => {
          console.log(evt.target.value);
          console.log(this)
          this.count = evt.target.value; // 将输入的值回显给表单变量;
          // 05 -1 错误赋值方法;
          this.state.count = evt.target.count;
          console.log("修改后的数据",this.state.count)//由于Object.freez,因此无法修改;
           // 05 -2;setState方法正确赋值方法;
           this.setState({
            count: count: evt.target.value
          })
        }
    render(){
    
      return (
        // 01 - react 和vue2一样,顶层元素只能有一个;
        <div>
          <input type="text" placeholder="请输入数据">
        </div>
        <hr/>
        <button>获取数据</button>
        // 01.2 - 修改后;
        <>
            <div>
         // 03 - 给表单提供一个value属性,没有onChange事件handler,它会被渲染成一个只读属性;
              <input type="text" placeholder="请输入数据" value={this.state.count} onChange={this.inputEvt}>
            </div>
            <hr />
         // 02 - react中绑定事件,{},所有的react的事件都是组合事件 -- react框架把原生事件进行了一个二次封装;
            <button onChange={this.getData}>获取数据</button>
        <> 
      )
      }
    }
    export default MyForm
    
  1. react 和vue2一样,顶层元素只能有一个;
  2. react中绑定事件,{},所有的react的事件都是组合事件 -- react框架把原生事件进行了一个二次封装,所有的事件名字和原生事件一样,区别在于原生事件名全部时小写,react组合事件是驼峰书写;
    1. onchange ==> onChange; onmouseover ==>onMouseOver;
    2. arguments 拿到的是合成事件:SyntheticBaseEvent
  3. 合成事件与组合事件
    1. 参考文献:https://juejin.cn/post/7525039240528461839
    2. 合成事件对象e,原生事件对象e.nativeEvent。打印结果:SytheticEvent, MouseEvent;
    3. 合成事件,非原生单兼容,统一浏览器事件接口,实现框架级性能优化;
    4. image
  1. 给表单提供一个value属性,没有onChange事件handler,它会被渲染成一个只读属性;
  2. react 中的视图、数据、事件:事件不能直接改变视图,只能先改变数据,数据再改变视图;
    1. change事件修改数据时,需要主动调用setState方法;
    2. this当心丢失,使用箭头函数或者.bind解决;
    3. react 中内部数据中都是state

03.03 props数据(组件外传值)

  1. props 及特点;
    1. react中外部数据都是props;
  2. 父子组件通信;
    1. 解构获取值
    2. this.props获取值
  • Cart.jsx代码块
      import React ,{Component} from "react"
      import Item from "./item.jsx"//名称定义合理可以不需要引用;
      export default Class Cart extends Component {
        // 1. 放在contructor构造器中没有区别;
        constructor() {
        // 1.1 constructor构造器中调用this时,一定先调用super方法;
          this.state = {
            list: Array.form(Array(6).fill("").map((item,i) => {
                id: "cart-" + i,
                name: "华为手机" + i,
                price: 3000,
                count: 1
            })) 
          }
        }
        render(){
          return(
            <div>
              <table className="table">
                <thead>
                  <tr>
                    <th>商品名称</th>
                    <th>单价</th>
                    <th>数量</th>
                  </tr>
                </thead>
                <tbody>
                  {
                      this.state.list.map((it) => {
                           return(
                              // 2.1 循环一定记得加key属性
                              // 2.2 类似vue传值:
                            <Item key={it.id} key={it.id} name={it.name} price={it.price} count={it.count}/>
                          )
                       })  
                    }
                </tbody>
              </table>
            </div>
          )
        }
      } 
    
  • item.jsx
      import React, {Component} from "react"
      export default class Item extends Component {
          render(){
            // 01.1-react绑定数据,类似给实例绑定数据;实例=this
            console.log(this)
            // 01.2- react绑定数据,解构;
            const {name, price, count} = this.props
            return{
            <tr>
              <td>{this.props.name}化为手机{name}</td>
              <td>{this.props.price}4000元{price}</td>
              <td>{this.props.count}数量{count}</td>
            </tr>
          }
        }
      }
    
  1. vscode插件库:es7+React; react的模板生成,输入rcc即可;

04 BUG整理;

04.01 使用cra脚手架页面报错;

  1. 问题

ctrl+s src下面的文件下时,随机在报错和正常的页面之间切换;
image

  1. 错因:
    1. react 和eslint 冲突;
  2. 解决:
    法1. package.json文件删除eslint-config (项目明确不需要使用eslint-config-react)
    法2. node_modules 中的文件版本冲突,删了重装;
  3. 参考文献:
    1. https://blog.csdn.net/ARandeCSDN/article/details/131604929

回顾

1.0 脚手架

  1. 脚手架;

    1. VUE => Vite;
    2. React => create-react-app;(cra);
  2. 安装命令:

    1. npx create-react-app projectName;
    2. pnpm install;
    3. pnpm start;
  3. Node版本控制在18.X以上;

  4. 项目目录;

    1. public文件夹下index.html代码的简化;(scanable="no",icon图标的路径);
    2. 初始搭建项目前删除git(提交到react版本管理库),公司的项目不删(项目提交记录)
    3. src 项目源码:依赖,WEBPACK,沙盒(可以释放但不推荐,且不可撤回)
  5. 开发特性:

    1. react引入;
    2. 组件式开发;
    3. 单元素;
    4. 单向数据流;

2.0 React基础知识

  1. 知识点汇总;

  2. 模块的基础引用;

  3. 创建root的组件 import ReactDom from 'react-dom/client'

  4. 创建类的组件; import React from "react";

  5. 组件内部使用的函数;

    • React.createRoot(document.querySelector("#root")).render()
    • ReactDom.createElement('h1',{style:{}},'你好')
  6. react创建组件的几种方式;

    • createElement
    • 创建对象;
      <> <h1>this is a title! </h2> <div>这是表体的基本内容!</div> </>
    • 继承对象
      Component; class Child1 extends Component{render(){return()}}
    1. 导入模块
    // 1. 导入React.createElement创建挂载组件
        // - 格式: ("div",{},...Child)
    // 2. 导入ReactDom.createRoot 创建根元素的组件;
    import React from "react"; 
    import ReactDom from "react-dom/client";
    
    const VNode = React.createElement(
      "div", // 易错为:{type:"div",}
      {
        style:{
          fontSize:"24px",
          color: "red"
        }
      },
      "你好朋友",
      React.createElement(
        "button",
        {
          style: {
            width: "100px",
            height: "80px",
          }
        },
        "打招呼"
      )
    )
    const root = ReactDom.createRoot(document.querySelector("#root"));
    root.render(VNode);
    
    
    2. 创建react组件
    // 1. createElement;
    const VNode1 = React.createElement(
      "h1",
    {
      style: {
        color: "red"
      },
      "hello world !",
      React.createElemtn()
    }
    
    )
    
  7. react 变量的函数的定义;

posted @ 2025-07-15 20:53  Saturday_to_Monday  阅读(13)  评论(0)    收藏  举报