后端开发浅学react

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

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

目录

jsx语法

jsx表达式案例

jsx条件渲染

jsx中的样式处理

函数组件的创建和渲染

组件与props

函数事件绑定

在事件中传递自定义参数

扫描二维码关注公众号,回复: 14990499 查看本文章

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

猜你喜欢

转载自blog.csdn.net/weixin_53142722/article/details/128342226