react 基础知识(一)

news2024/11/18 2:58:10

1、 安装1 (版本 react 18)

// 安装全局脚手架(create-react-app基于webpack+es6)
npm install -g create-react-app
//使用脚手架搭建项目
create-react-app my-app
// 打开目录
cd my-app
// 运行项目
npm start

目录结构

2、初体验

import React from 'react';
// 17写法
import ReactDOM from 'react-dom';
const root = document.getElementById('root');
ReactDOM.render(<App />, root);
// 18写法
import ReactDOM from 'react-dom/client';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <h1>hello</h1>
);

3、JSX(javascript+xml的语法)

概念:jsx是js和html混合的语法,将组件结构、数据、样式聚合在一起定义组件,会编译成普通的js

  • 遇到 < 开头,用html规则解析(标签必须闭合
  • 遇到 { 开头,用js规则解析
  • 样式style等于一个对象(属性使用驼峰式命名)
  • 声明类名用clssName=类名,因为class是js关键字
export default function App() {
  return (
    <div className="App">
    // { }里面是js表达式(变量的运算符组合,如a+b),必须返回一个值
      {
        arr.map(function(item,index){
        // 渲染后为style="background-color:green"
          return <span style={{backgroundColor:'green'}} className='read_name' key={index}>{item}</span>
          
        })
      }
    </div>
  );
}
  • 判断使用三目运算符、if、&&
    注: 勿将数字放在 && 左侧 {num&& < A />} 当num=0时,会渲染0
// 三目运算	{flag? <A /> : <B />} 表示 “当 flag为真值时, 渲染 <A />,否则 <B />”。
return <span style={{backgroundColor:index==0?'green':"pink"}} >张三</span>
// if判断	选择性返回jsx
if(flag){return <h1>张三 √</h1>}
return <h1>张三 </h1>
// &&	{flag&& <A />} 表示 “当 flag为真值时, 渲染 <A />,否则不渲染”
return (
  <h1>
    张三 {flag&& '✔'}
  </h1>
);
  • 渲染列表用map,filter可以筛选需要的组件
    循环列表时必须添加key值
// map遍历见上示例
// filter 示例
arr=[{name:'张三',age:20},{name:'李四',age:10}]
let newArr=arr.filter(item=>item.age>18)

jsx中使用js的规则:

  • 引号包含的值作为字符串传递
  • {} 包含js 逻辑与变量
  • {{}} 表示包含的是一个js对象
  • 它们在内容区域属性= 后面生效

4、组件

页面分割成多个组件,每个组件有自己的逻辑与样式,不同组件可组合成一个新的页面。可组合、可重用、可维护
组件类第一个字母必须大写,只能包含一个顶层标签可用div或者是空标签<></>包起来
注:凡是首字母小写都会被识别为react元素(html标签)

(1)声明组件(导出-声明-添加)

// 第一步:导出组件 export default  一个文件只能有一个default
// 第二步:声明组件   function App(){}
export default function App() {
// 第三步:添加标签
// return 与标签不在一行,必须用()b包起来,否则什么都不会返回
  return (
    <div className="App">hello</div>
  );
  // 或写成一行
  // return  <div className="App">hello</div>
}

(2)导入与导出

同一文件中,有且仅有一个默认导出,但可以有多个具名导出
图解

(3)创建组件的2种方式

第一种:函数式声明 ,function App(){} 静态组件,见(1)示例
第二种:类名组件 class App extends Component{}

import React,{Component } from 'react';
export default class App extends Component {
  // render 指该组件如何渲染,一定要返回一个react元素,且只能有一个根元素
  render(){
    return <h1>hello</h1>
  }
}

5、props(父子组件传参)

  • 传递props,需要将参数加到jsx中
  • 读取props,可使用function App({name,id})的解构语法
  • 可以指定默认值,函数式声明直接用name=“李四”,class声明用static defaultProps={name:‘李四’}
//1、函数式的demo
// 这里使用结构取出name,也可写成props.name
function Child({name}) { 
//可以给name附初始值 name="李四",当调用时没有传值,会使用默认值
// function Child({name="李四"}) { 
  return (
    <span>{name}</span>
  );
}
export default function App() {
  return (
    <div className="App">
      <Child name="张三"></Child>
  </div>
  );  
}
// 2、class类的demo
class Children extends Component{
  static defaultProps={name:'李四'} // 默认属性值,即父类调用不传递props,会使用这个默认的值
  render(){
    return(
      <h1>{this.props.name}</h1>
    )
  }
}
export default class App extends Component {  
  render(){
    return (
      <div>
        <Children name="张三"></Children>
        <Children ></Children> {/* 未传值会显示默认值“李四” */}
      </div>
    )
  }
}
  • class声明的组件可以使用prop-types指定props的类型和是否必填
// 第一步安装插件
npm install props-types -S 安装依赖
// 引入PropTypes 
import PropTypes from 'prop-types' 
class Children extends Component{
 // 定义组件的类型和是否必传
 static propTypes={
   name:PropTypes.string, // name类型为string
   age:PropTypes.number.isRequired // age   number,且必填
 }
 render(){
   return(
     <div>
       <h1>{this.props.name}</h1>
       <div>年龄:{this.props.age}</div>
     </div>
   )
 }
}
export default class App extends Component {
 render(){
   return (
     <div>
       {/* 错误写法 */}
       <Children name={1}></Children>
       {/*会提示报错,The prop `age` is marked as required in `Children`, but its value is `undefined`.
       Invalid  prop `name` of type `number` supplied to `Children`, expected `string`*/}
       
       {/* 正确写法 */}
       <Children name="张三" age={1}></Children>
     </div>
   )
 }
}

prop-types 常用类型 :array、bool、func、object、number、string、symbol、element
限制必要:PropTypes.类型.isRequired
仅限制必要:PropTypes. any.isRequired
多种类型:PropTypes.oneOfType([[PropTypes.string,PropTypes.number ])
多可选类型:PropTypes.oneOf([‘张三’,‘李四’])
特定结构对象:PropTypes.shape({name:类型,age:类型})

// 多种类型--以下代码就不会报错
 static propTypes={
    name:PropTypes.oneOfType([PropTypes.string,PropTypes.number]),
  }
<Children name={1}></Children>
// 多选类型--只能传递red和blue中的一个值,否则会报错,不能不传
static propTypes={
    color:PropTypes.oneOf(['red','blue']),
  }
 <Children color="red"></Children>  
 // 特定结构对象, 符合结构的才可以
 static propTypes={
    obj:PropTypes.shape({
        name: PropTypes.string.isRequired,
        age: PropTypes.number.isRequired
    })
  } // 符合obj={name:'xxx',age:数字}
  <Children obj={{name:'张三',age:14}}></Children>
  • props是只读,不可被修改
  • 像< Card>< Avatar />< /Card>这样的嵌套 JSX,将被视为 Card 组件的 children prop (类似于插槽)
function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

export default function App() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{ 
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}

6、状态state和事件处理

(1)state状态:组件内部变化的值

import React,{Component } from 'react';
export default class App extends Component {
  constructor(){
    super();
    this.state={name:'张三'}  // 自定义组件状态对象(组件内部变化的值,内部初始化内部改变)
  }
  // 生命周期函数   组件挂载完成
  componentDidMount(){
    // 调用setState ,状态会更新,还会重新调用render方法重新渲染
    this.setState({name:'李四'})
  }
  render(){
    return <h1>{this.state.name}</h1>
  }
}

setState是异步,不能在赋值后立即获取新state,可在其回调函数中获取

// 会先打印修改前的值,再打印修改后的值
handleClick=()=>{
        this.setState({
            num:this.state.num+1
        },()=>{
            console.log("获取修改后的值",this.state.num)
        })
        console.log("获取修改前的值",this.state.num)
    }

(2)事件处理:

class声明-----onClick={this.方法名}
function声明-----onClick={方法名}

// class声明onClick={this.方法名} 
export default class App extends Component {
  constructor(){
    super();
    this.state={heart:true}  
  }
  handleClick=()=>{
    this.setState({heart:!this.state.heart})
  }
  render(){
    return (
      <div>
        <span>心情{this.state.heart?'开心':'伤心'}</span>
        <button onClick={this.handleClick}>变心</button>
      </div>
    )
  }
}
// 函数式声明:onClick={方法名}--无实例无this
export default function App(){
    const handleClick=()=>{
        console.log('dianji')
    }
    return(
        <>
        <button onClick={handleClick}>点击</button>
        </>
    )
}

7、表单组件的双向绑定、refs

(1)双向绑定

受控组件:受当前组件的状态控制
非受控组件:不受当前组件状态控制

export default class App extends Component{
    constructor(){
        super()
        this.state={name:'张三'}
    }
    handleChange=(event)=>{
        // 通过获取输入框的值实现双向绑定
        this.setState({name:event.target.value})
    }
    render(){
        return (
        <div>
            <div>hello,{this.state.name}</div>
            {/* 受控组件,必须加change事件 */}
            <input onChange={this.handleChange} value={this.state.name}></input>
            {/* 非受控组件,随便输 */}
            <input onChange={this.handleChange} ></input>
        </div>
        )
    }
}

(2)refs:可获取DOM元素及其实例

class有三种(refs字符串、 refs回调函数、createRef)、

// class声明有实例,所以可以用字符串refs|回调函数|createRef()三种方式,以下是示例
export default class App extends Component{
    constructor(){
        super()
        this.myRef=React.createRef() // 3、createRef方式
    }
    handleChange=(event)=>{
        console.log(this.refs.test.value,'方式一:已废弃')
        console.log(this.b.value,'方式二:回调函数')
        console.log(this.myRef.current.value,'方式三:createRef,获取元素是.current')
    }
    render(){
        return (
        <div  onChange={this.handleChange}>
            {/* refs--字符串方式,已经被废弃,使用会被浏览器警告 */}
            <input ref="test"></input>
            {/* refs--回调函数,会执行2次,一次传参null,一次传参dom元素 */}
            <input ref={ref=>this.b=ref}></input>
            {/* refs--createRef方式,dom元素为.current属性*/}
            <input  ref={this.myRef}></input>
        </div>
        )
    }
}

function也有三种(useRef、React.forwardRef、React.useImperativeHandle)

// 因为function没有实例,所以不能用class的三种refs的方式
// 方式一:useRef,.current获取组件实例
export default function App(){
    const myRef=useRef(null)
    const handleClick=()=>{
        myRef.current.focus()
    }
    return(
        <>
        <input type="text" ref={myRef} />
        <button onClick={handleClick}>点击聚焦</button>
        </>
    )
}
// 方式二:forwardRef,该ref绑定的值是组件内ref绑定的节点而非组件实例,组件实例是不可以访问该回调ref函数
import React, { Component, forwardRef} from 'react';
const Test=forwardRef(function (props,ref){
    return <h1 ref={ref}></h1>
})
export default class App extends Component{
    constructor(){
        super()
        this.myRef=null
    }
    handleClick=()=>{
        this.myRef.innerHTML="加油哦"
    }
    render(){
        return (
        <div>
            <Test type="text" ref={ref=>this.myRef=ref} />
            <button onClick={this.handleClick}>点击聚焦</button>
        </div>
        )
    }
}
//方式三:useImperativeHandle,结合forwardRef使用
const Test=forwardRef(function (props,ref){
    const inputRef = React.useRef();
    React.useImperativeHandle(ref, () => ({
        focus: () => {
            inputRef.current.focus();
        },
    }));
    return <input ref={inputRef }/>
})
export default class App extends Component{
    constructor(){
        super()
        this.myRef=null
    }
    handleClick=()=>{
        this.myRef.focus()
    }
    render(){
        return (
        <div>
            <Test type="text" ref={ref=>this.myRef=ref} />
            <button onClick={this.handleClick}>点击聚焦</button>
        </div>
        )
    }
}

8、组件的生命周期

(1)class声明才有生命周期

声明周期图
声明周期执行示例:

export default class App extends Component{
    constructor(){
        super()
        this.state={num:0}
        console.log('constructor:初始化')
    }
    static getDerivedStateFromProps(){
        console.log('getDerivedStateFromProps:组件即将加载或发现state、props变化')
        return null
    }
    handleClick=()=>{
        console.log('准备变值')
        this.setState({
            num:this.state.num+1
        },()=>{
            console.log("获取修改后的值",this.state.num)
        })
    }
    shouldComponentUpdate(newProps,newState){
        console.log('shouldComponentUpdate:是否应该变化')
        return !newState.num%5==0
    }
    getSnapshotBeforeUpdate(){
        console.log('getSnapshotBeforeUpdate:将要更新')
        return null
    }
    componentDidUpdate(){
        console.log('componentDidUpdate:更新结束')
    }
    render(){
        console.log('render:组件开始挂载')
        return (
        <div>
            <p>{this.state.num}</p>
            <button onClick={this.handleClick}>点击聚焦</button>
        </div>
        )
    }
    componentDidMount(){
        console.log('componentDidMount:组件挂载完成')
    }
    componentWillUnmount(){
        console.log('componentWillUnmount:卸载前')
    }
    
}

挂载更新
注:componentWillMount、componentWillUpdate、componentWillReceiveProps已经被官方废弃,请尽量用上图的生命周期函数

(2)函数式声明没有生命周期,一般用useEffect替代

其作用同componentDidMount、componentDidUpdate、componentWillUnmount

export default function App(){
    const [num, setNum] = useState(0);
    const [num1, setNum1] = useState(1)
    // 1、useEffect 第二个参数为空useEffect(()=>{}),初始化渲染之后执行一次,当页面所有数据变化时也会执行一遍,同componentDidMount、componentDidUpdate,-----初始化执行、点击按钮1和2都会执行
    // 2、useEffect 第二个参数为空数组useEffect(()=>{},[]),初始化渲染render之后只执行一次,数据变化不执行,同componentDidMount---初始化执行、点击按钮1、2不执行
    // 3、useEffect 第二个参数为监听值,useEffect(()=>{},[num]),初始化渲染render之后执行一次,监听元素变化执行一次,同componentDidMount、componentDidUpdate----初始化执行、点击按钮2才会执行
    useEffect(()=>{
        console.log('useEffect')
    },[num1])
    // 4、useEffect 第一个函数返回一个函数,表示在组件卸载前执行,同componentWillUnmount  useEffect(()=>{return ()=> {// 在此走一些收尾工作,如清除定时器/取消订阅等}},[stateValue])
    return(
        <>
        <p>{num}</p>
        <button onClick={()=>setNum(num+1)}>点击1</button>
        <p>{num1}</p>
        <button onClick={()=>setNum1(num1+1)}>点击2</button>
        </>
    )
}

  1. 若安装脚手架时报以下错,将npm切换成淘宝镜像即可安装成功
    报错截图 ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/956544.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#-单例模式

文章目录 单例模式的概述为什么会有单例模式如何创建单例模式1、首先要保证&#xff0c;该对象 有且仅有一个2、其次&#xff0c;需要让外部能够获取到这个对象 示例通过 属性 获取单例 单例模式的概述 总结来说&#xff1a; 单例 就是只有 一个实例对象。 模式 说的是设计模式…

汽车售后接待vr虚拟仿真实操演练作为岗位培训的重要工具和手段

汽车虚拟仿真教学软件是一种基于虚拟现实技术的教学辅助工具。它能够模拟真实的汽车环境和操作场景&#xff0c;让学生能够通过虚拟仿真来学习和实践汽车相关知识和技能。与传统的教学方式相比&#xff0c;汽车虚拟仿真教学软件具有更高的视觉沉浸感和互动性&#xff0c;能够更…

OpenCV(五):图像颜色空间转换

目录 1.图像颜色空间介绍 RGB 颜色空间 2.HSV 颜色空间 3.RGBA 颜色空间 2.图像数据类型间的互相转换convertTo() 3.不同颜色空间互相转换cvtColor() 4.Android JNI demo 1.图像颜色空间介绍 RGB 颜色空间 RGB 颜色空间是最常见的颜色表示方式之一&#xff0c;其中 R、…

小文智能GPT助手介绍

如何使用小文交互的GPT助手&#xff0c;让AI更加智能&#xff0c;适用更多场景&#xff1f; 在小文智能最新推出的4.0版本&#xff0c;有一个新功能&#xff0c;叫做GPT助手。GPT助手&#xff0c;顾名思义&#xff0c;即在小文智能的场景中&#xff0c;接入ChatGPT&#xff0c…

阿里云部署开源MQTT平台mosquitto的docker操作

MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的消息传输协议&#xff0c;广泛用于物联网和传感器网络中。Mosquitto是一个流行的开源MQTT代理&#xff0c;可以在Docker中进行配置和部署。本文将详细介绍如何在Docker中配置Mosquitto MQTT代理…

使用VBA将不同工作表拆分为单独的工作簿:实战指南

实现步骤 在处理大量数据时&#xff0c;Excel工作簿常常包含多个工作表。有时&#xff0c;我们需要将这些不同的工作表拆分为单独的工作簿&#xff0c;以便于分别处理或保存。这种情况下&#xff0c;我们可以利用VBA来实现这一目标。 VBA是一种基于Visual Basic的编程语言&…

详解MAC帧、ARP、DNS、ICMP协议

局域网通信原理 比如新建了一个内网&#xff0c;如果一台机器A找机器B&#xff0c;封FRAME时&#xff08;OSI的第二层用的数据格式&#xff09;&#xff0c;要封装对方的MAC&#xff0c;开始时A不知道B的MAC&#xff0c;只知道IP&#xff0c;它就发一个ARP包&#xff0c;源IP是…

信息安全法规和合规指南: 解析不同地区的信息安全法规要求,提供合规实践建议和资源推荐

第一章&#xff1a;引言 随着数字化时代的到来&#xff0c;信息安全已经成为企业不可忽视的重要议题。各个地区纷纷制定了信息安全法规&#xff0c;以确保个人隐私和敏感数据的保护。本文将深入探讨不同地区的信息安全法规要求&#xff0c;并提供合规实践建议和资源推荐&#…

一百六十九、Hadoop——Hadoop退出NameNode安全模式与查看磁盘空间详情(踩坑,附截图)

一、目的 在海豚跑定时跑kettle的从Kafka到HDFS的任务时&#xff0c;由于Linux服务器的某个文件磁盘空间满了&#xff0c;导致Hadoop的NodeName进入安全模式&#xff0c;此时光执行hdfs dfsadmin -safemode leave命令语句没有效果&#xff08;虽然显示Safe mode is OFF&#x…

JVM的故事——虚拟机字节码执行引擎

虚拟机字节码执行引擎 文章目录 虚拟机字节码执行引擎一、概述二、运行时栈帧结构三、方法调用 一、概述 执行引擎Java虚拟机的核心组成之一&#xff0c;它是由软件自行实现的&#xff0c;能够执行那些不被硬件直接支持的指令集格式。 对于不同的虚拟机实现&#xff0c;执行引…

css强制显示一行

要强制将文本内容显示在一行中&#xff0c;可以使用CSS的white-space属性和overflow属性来实现。 首先&#xff0c;将white-space属性设置为nowrap&#xff0c;这样文本内容就不会换行。然后&#xff0c;将overflow属性设置为hidden&#xff0c;这样超出一行的内容就会被隐藏起…

从零开始探索C语言(五)----函数和作用域

文章目录 1. 函数1.1 函数定义1.2 函数声明1.3 函数调用1.3.1 传值调用1.3.2 引用调用 2. 作用域2.1 局部变量2.2 全局变量2.3 形式参数 1. 函数 函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数&#xff0c;即主函数 main() &#xff0c;所有简单的程序都可以…

直接插入排序与希尔排序

目录 一&#xff0c;排序的概念 二&#xff0c;插入排序 2.1直接插入排序 2.2 希尔排序 一&#xff0c;排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些或某些关键字的大小&#xff0c;递增或递减的排列 稳定性&#xff…

flutter自定义按钮-文本按钮

目录 前言 需求 实现 前言 最近闲着无聊学习了flutter的一下知识&#xff0c;发现flutter和安卓之间&#xff0c;页面开发的方式还是有较大的差异的&#xff0c;众所周知&#xff0c;android的页面开发都是写在xml文件中的&#xff0c;而flutter直接写在代码里&#xff08;da…

无重叠区间【贪心算法】

无重叠区间 给定一个区间的集合 intervals &#xff0c;其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量&#xff0c;使剩余区间互不重叠 。 class Solution {public int eraseOverlapIntervals(int[][] intervals) {//先排序&#xff0c;按照左边界升序,注…

Vue3 select循环多个,选项option不能重复被选

Vue3 select循环多个&#xff0c;选项option不能重复被选 环境&#xff1a;vue3tsviteelement plus 实现目标&#xff1a;Vue3 select循环多个&#xff0c;当其中一个option值被选后&#xff0c;其他select里面不能再重复选择该option值。第二种&#xff0c;当其中一个option值…

雅思写作 三小时浓缩学习顾家北 笔记总结(二)

目录 饥饿网一百句翻译 Using government funds for pollution cleanup work can create a comfortable environment. "Allocating government funds to pollution cleanup work can contribute to the creation of a comfortable environment." Some advertise…

Linux的基本使用和Web程序部署(JavaEE初阶系列18)

目录 前言&#xff1a; 1.Linux 1.1Linux是什么 1.2Linux发行版 1.3Linux环境搭建 1.3.1环境搭建方式 1.3.2使用云服务器 1.4使用终端软件连接到Linux 1.4.1什么是终端软件 1.4.2使用Xshell登录主机 1.5Linux常用的命令 1.5.1ls 1.5.2cd 1.5.3pwd 1.5.4touch 1.…

vscode html使用less和快速获取标签less结构

扩展插件里面搜索 css tree 插件 下载 使用方法 选择你要生成的标签结构然后按CTRLshiftp 第一次需要在输入框输入 get 然后选择 Generate CSS tree less结构就出现在这个里面直接复制到自己的less文件里面就可以使用了 在html里面使用less 下载 Easy LESS 插件 自己创建…

Python爬虫-某网酒店数据

前言 本文是该专栏的第5篇,后面会持续分享python爬虫案例干货,记得关注。 本文以某网的酒店数据为例,实现根据目标城市获取酒店数据。具体思路和方法跟着笔者直接往下看正文详细内容。(附带完整代码) 正文 地址:aHR0cHM6Ly93d3cuYnRoaG90ZWxzLmNvbS9saXN0L3NoYW5naGFp …