后端开发浅学react

news2024/11/18 10:25:09

博客笔记来自于学习  柴柴老师在b站分享的react学习视频,仅供学习参考学习视频是来自于b站的:柴柴_前端教书匠视频链接:React入门到实战(2022全网最新)_哔哩哔哩_bilibili

react官网  开始 – React (docschina.org)

目录

jsx语法

jsx表达式案例

jsx条件渲染

jsx中的样式处理

函数组件的创建和渲染

组件与props

函数事件绑定

在事件中传递自定义参数

props只读性

箭头函数的写法可以解决this指向

解构赋值

useState

useEffect


jsx语法

jsx表达式案例

语法:{ JS 表达式 } 注意这个{}里面只能写表达式,不能写语句!!!

可以使用的表达式:

  • 字符串、数值、布尔值、null、undefined、object( [] / {} )

  • 1 + 2、'abc'.split('')、['a', 'b'].join('-')

  • fn()

案例:

//1.识别我们的常规变量
const name = "react 学习"

//2.原生js中的调用
const getAge = () =>{
  return "永远的18";
}

//3.三元运算符(常用)
const flag  = false;

function App() {
  return (
    <div className="App">
      {name}<br></br>
      {getAge()}<br></br>
      {flag ? '18':'68'}
    </div>
  );
}

export default App;

jsx条件渲染

作用:根据是否满足条件生成HTML结构,满足条件才进行渲染。

实现:可以使用 三元运算符逻辑与(&&)运算符

// 来个布尔值
const flag = true
function App() {
  return (
    <div className="App">
      {/* 条件渲染字符串 */}
      {flag ? 'react真有趣' : 'vue真有趣'}
      {/* 条件渲染标签/组件 */}
      {flag ? (<span>this is span</span>) : null}
    </div>
  )
}
export default App

如果我们遇到了 复杂的多分支的逻辑,那么应该怎么办呢?肯定是不能三元套三元的,这样会导致代码的可读性非常弱。

原则:模板中的逻辑尽量保持精简。 收敛为一个函数,通过一个专门的函数来写分支逻辑,模板中只负责调用。

const getTag = (type)=>{
    if(type === 1){
        return <h1>this h1</h1>
    }
    if(type === 2){
        return <h2>this h2</h2>
    }
    if(type === 3){
        return <h3>this h1</h3>
    }
}

function App() {
return (
    <div className="App">
    getTag(1)
    </div>
);
}
  
export default App;

jsx中的样式处理

注意:使用样式处理的时候,需要使用两个{}来进行包裹,第一个{}的作用是为了让第二个{}识别为对象,第二个{}是对象,用来写我们的样式属性。

1、行内样式 - style (在元素身上绑定一个style属性即可)

function App() {
  return (
    <div className="App">
      <div style={{ color: 'red' }}>this is a div</div>  //所以以后看见两个{}要知道是在干啥
    </div>
  )
}
export default App

2、行内式 - style - 更优写法 (把样式以对象抽离出来)

const styleObj = {
    color:red
}
function App() {
  return (
    <div className="App">
      <div style={ styleObj }>this is a div</div>
    </div>
  )
}
export default App

3、类名 - className(推荐)(在元素身上绑定一个className属性即可)

.active{
    color:blue;
}
import './app.css'
function App() {
  return (
    <div className="App">
      <span className='active'>测试类名样式</span>
    </div>
  )
}
export default App

函数组件的创建和渲染

组件与props

组件:组件,从概念上类似于 JavaScript 函数。它接受任意的入参(即 “props”),并返回用于描述页面展示内容的 React 元素。

当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 “props”。

先看一个react官网给的案例:下面的代码会输出:Hello Sara

function Welcome(props) {  //自定义组件
  return <h1>Hello, {props.name}</h1>;
}

//如果是类组件 那么使用this来获取
//class Square extends React.Component {
//  render() {
//    return (
//      <button className="square">
//        {this.props.name}
//      </button>
//    );
//  }
//}

const element = <Welcome name="Sara" />;  //在jsx中使用自定义组件 Welcome,并且传了一个属性name给Welcome组件,Welcome组件可以用props来接收使用Welcome组件的jsx中传过来的属性或者是对象
ReactDOM.render(
  element,
  document.getElementById('root')
);

让我们来看看这个例子中发生了什么:

  1. 我们调用 ReactDOM.render() 函数,并传入 <Welcome name="Sara" /> 作为参数。

  2. React 调用 Welcome 组件,并将 {name: 'Sara'} 作为 props 传入

  3. Welcome 组件将 <h1>Hello, Sara</h1> 元素作为返回值。

  4. React DOM 将 DOM 高效地更新为 <h1>Hello, Sara</h1>

约定说明

  1. 组件的名称必须首字母大写,react内部会根据这个来判断是组件还是普通的HTML标签。

  2. 函数组件必须有返回值,返回的值表示该组件的 UI 结构;如果不需要渲染任何内容,则返回 null。

  3. 组件就像 HTML 标签一样可以被渲染到页面中。组件表示的是一段结构内容,对于函数组件来说,渲染的内容是函数的返回值就是对应的内容。

  4. 使用函数名称作为组件标签名称,可以成对出现也可以自闭合。

import React from "react"

//创建函数式组件
function Hello () {
  return <div>hello</div>
}

//类组件的创建和渲染
class HelloCompoent extends React.Component {
  //这个render函数是必须的
  render () {
    return <div>this is class component</div>
  }
}
function App () {
  return (

    <div className="App">
      {/* 渲染hello组件 */}
      <Hello></Hello>

      {/* 渲染类组件 */}
      <HelloCompoent></HelloCompoent>
    </div>
  )
}
export default App

函数事件绑定

  • 语法 on + 事件名称 = { 事件处理程序(回调函数) } ,比如:<div onClick={ onClick }></div>

  • 注意点 react事件采用驼峰命名法,比如:onMouseEnter、onFocus

函数事件绑定:

import React from "react"

//创建函数式组件
function Hello () {
//创建一个事件(相当于一个方法)  这种类似java的lambada表达式的写法是react中声明事件的标准写法,可以避免一些不必要this指向问题
  const clickHandler = () => {
    console.log('函数组件中的事件被触发了')
  }
  //绑定事件
  return <div onClick={clickHandler}>hello</div>
}

function App () {
  return (
    <div className="App">
      {/* 渲染hello组件 */}
      <Hello></Hello>
    </div>
  )
}

export default App

在事件中传递自定义参数

场景:就是我们想在触发事件的时候,传递一些自定义参数,应该怎么操作?

import React from "react"

//创建函数式组件
function Hello () {
  //创建一个事件(相当于一个方法)
  const clickHandler = (msg) => {
    console.log('函数组件中的事件被触发了', msg)
  }
  //需要在调用的时候传递实参,需要修改函数组件触发的调用方式了  : 改造成箭头函数的调用方式就行
  return <div onClick={()=>clickHandler('this is msg')}> 点击 </div>
  {/*之前的调用方式<div onClick={clickHandler}>点击</div> */}
}
function App () {
  return (

    <div className="App">
      {/* 渲染hello组件 */}
      <Hello></Hello>
    </div>
  )
}
export default App

 如果我们想要既传递 e 又要想要传递自定义参数,那么应该怎么操作?

import React from "react"

//创建函数式组件
function Hello () {
  //创建一个事件(相当于一个方法)
  const clickHandler = (e,msg) => {
    console.log('函数组件中的事件被触发了', e,msg)
  }
  //需要在调用的时候传递实参,需要修改函数组件触发的调用方式了  : 改造成箭头函数的调用方式就行  并且需要注意形参和实参的顺序
  return <div onClick={(e)=>clickHandler(e,'this is msg')}> 点击 </div> {/* 需要先捕获e然后再传递到绑定的事件中*/}
  {/*
  之前不需要传递参数的调用方式<div onClick={clickHandler}>点击</div>
  之前传递一个自定义参数的调用方式:return <div onClick={()=>clickHandler('this is msg')}> 点击 </div> 
  */}
}
function App () {
  return (

    <div className="App">
      {/* 渲染hello组件 */}
      <Hello></Hello>
    </div>
  )
}
export default App

总结:

1、只需要一个额外参数 写法: {clickHandler} -> { () => clickHandler('自定义参数')}

2、既需要e也需要额外的自定义参数 {(e) => clickHandler(e,'自定义的参数') }

props只读性

在 组件与props中 我们已经简单的说明了一下props的作用,这里单独的来介绍一下props的只读性。

组件无论是使用 函数声明还是通过class 声明 ,都决不能修改自身的 props。

function sum(a, b) {
  return a + b;
}
这样的函数被称为“纯函数”,因为该函数【不会尝试更改入参】,且多次调用下相同的入参始终返回相同的结果。
相反,下面这个函数则不是纯函数,因为它更改了自己的入参:
function withdraw(account, amount) { //account中的total属性被更改了
  account.total -= amount;
}

所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。

在不违反上述规则的情况下,state 允许 React 组件随用户操作、网络响应或者其他变化而动态更改输出内容。

箭头函数的写法可以解决this指向

import React from "react"
class Test extends React.Component { 

  change(){
    console.log(this)  //输出的this是组件的实例属性
  }

  render () {
    return (
      <div>
         {/*如果不通过constructor做修正,那么我们可以直接在事件绑定的位置通过箭头函数的写法 --> 这种写法是直接沿用父函数(render)中的this  这个函数的父函数是render,这也说明了render中的this指向的就是【当前组件】的实例对象(react内部进行了修正)  */}
        <button onClick={()=>this.change()}>click</button>
      </div>
    )
  }
}

function App () {
  return (
    <div className="App">
      {/* 渲染定义的类组件 */}
      <Test></Test>
    </div>
  )
}
export default App

建议:在开发中定义函数式组件的时候直接就 handle = () => {} 来定义就行,然后引用的时候直接通过 this.handle来使用。

解构赋值

参考来源:解构赋值 - JavaScript | MDN (mozilla.org)

解构赋值:可以将数组中的值或对象的属性取出,赋值给我们新声明的变量

  • var定义变量,没有块的概念,可以跨块访问,不能跨函数访问,不初始化出现undefined,不会报错

  • let定义变量,只能在块作用域里访问,也不能跨函数访问,对函数外部无影响。

  • const定义常量,只能在块作用域里访问,也不能跨函数访问,使用时必须初始化(即必须赋值),而且不能修改

先看基础使用的案例:

// 数组的解构 会按照变量的顺序进行解构
const x = [1, 2, 3, 4, 5];
const [y, z] = x;
console.log(y); // 1
console.log(z); // 2

const foo = ['one', 'two', 'three'];
const [red, yellow, green] = foo;
console.log(red); // "one"
console.log(yellow); // "two"
console.log(green); // "three"


//解构对象中的属性  对象中的
const obj = { a: 1, b: 2 };
const { a, b } = obj;
// 相当于下面的赋值写法
// const a = obj.a;
// const b = obj.b;

const obj2 = {  x:"你好", c: 2 };
const { x, c } = obj2;
console.log(x) //你好
console.log(c) //2

//报错
const obj3 = {  "你好", d: 2 };
const { x, c } = obj3;
console.log(x) 
console.log(d) 

const obj4 = {  x:"你好", e: 2 };
const { ddddd, e } = obj4;
console.log(ddddd) // undefined
console.log(e) //2

//如果想把属性赋值给新的变量名 那么应该怎么操作?
const obj4 = {  x:"你好", e: 2 };
const { x:ddddd, e } = obj4;
console.log(ddddd) // 你好
console.log(e) //2

组合对象与数组的解构赋值:案例:想要下面 props 数组中的第三个元素,同时只需要对象中的 name 属性

const props = [
  { id: 1, name: 'a'},
  { id: 2, name: 'b'},
  { id: 3, name: 'c'}
];

const [,, { name }] = props;

console.log(name); // "c"

默认值:每个解构属性都可以有一个默认值当属性不存在或值为 undefined 时,将使用默认值。如果属性的值为 null,则不使用它。

const [a = 1] = []; // a 是 1
const { b = 2 } = { b: undefined }; // b 是 2
const { c = 2 } = { c: null }; // c 是 null

剩余属性:你可以使用剩余属性(...rest)结束解构模式。此模式会将对象或数组的所有剩余属性存储到新的对象或数组中。(用的挺多的)

const { a, ...others } = { a: 1, b: 2, c: 3 };
console.log(others); // { b: 2, c: 3 }

const [first, ...others2] = [1, 2, 3];
console.log(others2); // [2, 3]

useState

案例演示:

// userState()就是我们使用的函数,我们可以在()中传一个初始值,这个初始值会被赋值给你声明的变量count,如果你想在其他地方修改这个count,那么可以调用声明的setCount()方法  并且把新的count值传到这个()中  setCount(newCount)
const [count, setCount] = useState(0); // 参数:状态初始值比如,传入 0 表示该状态的初始值为 0,返回值:数组,包含两个值:第一个是表示:状态值(state) 第二个是表示:修改该状态的函数(setState)


import { useState } from 'react'
function App() {
  // 参数:状态初始值比如,传入 0 表示该状态的初始值为 0
  // 返回值:数组,包含两个值:1 状态值(state) 2 修改该状态的函数(setState)
  const [count, setCount] = useState(0)
  return (
    <button onClick={() => { setCount(count + 1) }}>{count}</button>
  )
}
export default App

状态的读取和修改:

  • 读取状态:该方式提供的状态,是函数内部的局部变量,可以在函数内的任意位置使用

  • 修改状态

    • setCount是一个函数,参数表示最新的状态值

    • 调用该函数后,将使用新值替换旧值

    • 修改状态后,由于状态发生变化,会引起视图变化

      注意:

      • 修改状态的时候,一定要使用新的状态替换旧的状态,不能直接修改旧的状态,尤其是引用类型

      • useState 的初始值(参数)只会在组件第一次渲染时生效。也就是说,以后的每次渲染,useState 获取到都是最新的状态值,React 组件会记住每次最新的状态值

import { useState } from 'react'

function App() {
  const [count, setCount] = useState(0)
  // 在这里可以进行打印测试
  console.log(count)
  return (
    <button onClick={() => { setCount(count + 1) }}>{count}</button>
  )
}
export default App

useState 注意事项 :

  • 只能出现在函数组件或者其他hook函数中

  • 不能嵌套在if/for/其它函数中(react按照hooks的调用顺序识别每一个hook)

let num = 1
function List(){
  num++
  if(num / 2 === 0){
     const [name, setName] = useState('cp') 
  }
  const [list,setList] = useState([])
}
// 俩个hook的顺序不是固定的,这是不可以的!!!

useEffect

什么是副作用:一个函数除了主作用,其他的作用就是副作用。对于 React 组件来说,主作用就是根据数据(state/props)渲染 UI,除此之外都是副作用

常见的副作用

  1. 数据请求 ajax发送

  2. 手动修改dom

  3. localstorage操作

使用步骤

  1. 导入 useEffect 函数

  2. 调用 useEffect 函数,并传入回调函数

  3. 在回调函数中编写副作用处理(dom操作)

  4. 修改数据状态 (配合useState中的set方法一起使用)

  5. 检测副作用是否生效

import { useEffect, useState } from 'react'

function App() {
  const [count, setCount] = useState(0)
 
  // useEffect() 调用副作用函数  ()=>{} 回调函数
  useEffect(()=>{
    // dom操作  进行操作
    document.title = `当前已点击了${count}次`
  })
  return (
    <button onClick={() => { setCount(count + 1) }}>{count}</button>
  )
}

export default App

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

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

相关文章

谁会嫌钱多啊,最适合学生党的Python兼职攻略以及接私活经验

大家好&#xff0c;我是小八 这次我想谈谈一个非常热门的话题&#xff0c;就是如何在学习python的同时去赚钱。在这篇文章中&#xff0c;你会学习到如何通过学习python来赚取副业收入。 相信大家都对钱感兴趣吧&#xff0c;如果你和马云爸爸对钱不敢兴趣的话&#xff0c;那这…

Lambda表达式从用到底层原理

文章目录前言一、lambda函数基本使用参数列表返回类型函数体捕获列表值捕获引用捕获隐式捕获混合方式捕获修改值捕获变量的值异常说明二、lambda表达式使用的注意事项避免默认捕获模式三、lambda表达式底层实现原理采用值捕获采用引用捕获前言 lambda式作为一种创建函数对象的…

Python tkinter -- 第18章 画布控件之多边形

18.2.19 create_polygon(coords, **options) 根据 coords 给定的坐标&#xff0c;在画布上绘制一个多边形。 &#xff08;1&#xff09;coords&#xff1a;给定多边形的坐标 &#xff08;2&#xff09;options&#xff1a;选项的具体含义&#xff1a; 选项含义activedash当鼠标…

JavaEE- JVM八股文(JVM垃圾回收机制GC)

JVM垃圾回收的目标&#xff1a;主要针对内存中的堆空间进行垃圾回收。 Java中&#xff0c;大量的内存都在堆中。 程序计数器&#xff1a;固定大小&#xff0c;不涉及释放 栈&#xff1a;函数执行完毕&#xff0c;对应栈的空间就自动释放了&#xff0c;不需要垃圾回收 方法区&…

07-Golang中标识符的命名规则

Golang中标识符的命名规则标识符概念标识符的命名规则保留关键字介绍预定义标识符介绍标识符命名注意事项标识符概念 1.Golang对各种变量、方法等命名时使用的字符序列称为标识符 2.凡是自己可以起名字的地方都叫标识符 标识符的命名规则 1.由26个英文字母大小写&#xff0…

华为云桌面之下的“冰山”:技术底座x繁荣生态加速模式进化

在新兴技术迭代升级持续加速的背景下&#xff0c;很多产品类别的内涵和外延都在不断演进——虽然名字没什么变化&#xff0c;但实际所指已有云泥之别。 “云桌面”即是如此。从早期的无盘工作站&#xff0c;到VDI、IDV和VOI等技术流派的群雄并起&#xff0c;云桌面的江湖总是“…

linux第七章---管道、环境变量、常用命令

1.管道 1.1概念&#xff1a; 管道类似于文件重定向&#xff0c;可以将前一个命令的stdout重定向到下一个命令的stdin。 1.2要点&#xff1a; 管道命令仅处理stdout&#xff0c;会忽略stdeer。管道右边的命令必须要能接受stdin.多个管道命令可以串联。 1.3与文件重定向的区…

Java平衡树之查找树的详解(1)

1.平衡树 之前我们学习过二叉查找树&#xff0c;发现它的查询效率比单纯的链表和数组的查询效率要高很多&#xff0c;大部分情况下&#xff0c;确实是这样的&#xff0c;但不幸的是&#xff0c;在最坏情况下&#xff0c;二叉查找树的性能还是很糟糕。例如我们依次往二叉查找树中…

c语言预处理(万字解析)

预处理一.总体概述1.注释去除2.宏替换二.宏定义&#xff08;宏替换类型&#xff09;1.数值宏常量2.字符串宏常量3.用宏定义注释符号4.用宏定义表达式&#xff08;难点&#xff09;1.第一种情况2.第二种情况5.#undef&#xff08;宏的有效范围&#xff09;1.两个问题2.#undef的使…

FLStudio2023水果软件哪个版本好用?功能区别对比

FL Studio是一款功能非常强大的音乐创作编辑软件它就是FL Studio(水果软件)。使用FL Studio中文版可以轻松帮我们制作自己的音乐唱片&#xff0c;拥有强大且专业的编曲混音创作工具&#xff0c;有需要的朋友不要错过。 水果&#xff0c;全称Fruity Loop Studio&#xff0c;简称…

量子计算(十六):其他类型体系的量子计算体系

文章目录 其他类型体系的量子计算体系 一、离子阴量子计算 二、原子量子计算 三、核自旋量子计算 四、拓扑量子计算 其他类型体系的量子计算体系 一、离子阴量子计算 离子研量子计算在影响范围方面仅次于超导量子计算。早在2003年&#xff0c;基于离子阴就可以演示两比特…

“转行做程序员”很难?这里有4个重要建议

近几年来&#xff0c;传统行业多处于经济下行&#xff0c;加上互联网行业的赚钱效应&#xff0c;想要转行到这一行的人越来越多&#xff0c;其中程序员这个行业更是很多人梦寐以求的。 但另一方面&#xff0c;我们也发现&#xff0c;这些想要转行的同学们往往会遇到很多困扰。…

推荐今日 火火火火 的开源项目

本期推荐开源项目目录&#xff1a;1. coding-interview-university2. 前端后台管理模板3. 钉钉聊天机器人4. 基于 ChatGPT 的 Neovim 插件5. 开源的分布式社交网络平台6. 分析社交媒体内容7. 用于绘制流程图的库01coding-interview-university这是一个汇集了软件工程师面试中常…

2023跨年代码(烟花+背景音乐)

文章目录前言效果展示使用方法源码学习HTML代码CSS代码前言 时光荏苒&#xff0c;白驹过隙。2022这一年又在忙碌中度过了&#xff0c;过去的一年&#xff0c;我们同努力&#xff0c;我们共欢笑&#xff0c;每一次成功都蕴藏着我们辛勤的劳动。 新的一年即将来到&#xff0c;我…

【linuxgdb】动态链接和静态链接的区别,gdb的基础使用

目录 1.gcc/c动态链接和静态链接的区别 2.gdb的基础使用 2.2使用gdb调试 1.gcc/c动态链接和静态链接的区别 1.1查看可执行文件是动态还是静态的 格式&#xff1a;file文件名 1.2动态链接和静态链接 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的…

ARM S5PV210 串行通信接口详解

一、串行通信接口详解 1 0. 串口的名称 S5PV210 的数据手册中串口控制器在 section8.1串口的官方名称叫&#xff1a;universal asynchronous reciver and transmitter&#xff0c;通用异步收发器 英文缩写是uart&#xff0c;中文简称串口。 1. S5PV210 的串口控制器工作原理…

CSS -- 2D转换各属性讲解(translate,rotate,scale)

文章目录2D转换1 二维坐标系2 2D转换之移动 translate3 2D转换之旋转 rotate4 2D转换中心点 transform-origin5 2D转换之缩放scale6 2D转换综合写法7 2D转换总结2D转换 转换(transform)是CSS3中具有颠覆性的特征之一&#xff0c;可以实现元素的位移、旋转、缩放等效果 转换(t…

[ 常用工具篇 ] 使用 kali 实现网络钓鱼 -- setoolkit 详解实战(一)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

密码学讲座PPT

来自山大密码学讲座的PPT。 一些密码学领域常用名词术语 Diffie-Hellman 密钥交换&#xff1b;Elgamal 加密和签名&#xff1b;DSA 签名&#xff1b;因相应的离散对数问题难解&#xff0c;大素数的原根可用于密钥交换;RSA加密和签名: 因大整数因子分解难算&#xff0c;合数可成…

JetPack 组件总结

文章目录JetPackLifecycle使用Lifecycle解耦页面和组件使用Lifecycle解耦Service与组件使用ProcessLifecycleOwner监听应用程序生命周期ViewModel 与 LiveDataViewModelLiveDataViewModel LiveData 实现Fragment间通信DataBinding 的意义与应用意义使用前的配置import标签事件…