React基础学习

React基础

📣 📣 📣 📢📢📢

☀️☀️点开就是缘分认识一下,我是小冷。是一个兴趣驱动自学练习两年半的的Java工程师。

📒 一位十分喜欢将知识分享出来的Java博主⭐️⭐️⭐️,擅长使用Java技术开发web项目和工具

📒 文章内容丰富:覆盖大部分java必学技术栈,前端,计算机基础,容器等方面的文章

📒 如果你也对Java感兴趣,关注小冷吧,一起探索Java技术的生态与进步,一起讨论Java技术的使用与学习

✏️高质量技术专栏专栏链接: 微服务数据结构netty单点登录SSMSpringCloudAlibaba
😝公众号😝想全栈的小冷 ,分享一些技术上的文章,以及解决问题的经验

当前专栏React系列

React核心价值与前置知识

核心价值

  • 组件化(易开发易维护)

  • 数据驱动视图 :定义好数据和ui的显示规则 即UI=f(state)

    • 只关注业务数据修改,不在操作DOM 增加开发效率

使用vite创建Recat项目

开发规范

使用 prettier & eslint 规范开发

  • eslint 检查语法语义
  • prettier 检查代码风格
shell 复制代码
#eslint :
npm install eslint@typescript-eslint/parser @typescript-eslint/eslint-plugin --save-dev

#prettier:
npm install prettier eslint-config-prettier eslint-plugin-prettier --save-dev

vite和 webpack的区别

webpack是一个非常流行的前端打包工具 比较经典 Create-React-App 是使用webpack作为打包工具的

vite 既是构建工具 又是打包工具

vite的特点:

  1. Vite打包项目 在启动和代码更新时更快
  2. vite使用了 es Module 语法(仅开发环境)

React JSX语法

内容 :

  1. JSX语法
  2. 组件和props
  3. 实战: 列表页

JSX特点:

  1. JSX是js的扩展 写在js代码里面 组件的ui结构
  2. 语法和html很相似
  3. 不只是React独有

标签

  • 首字母大小写的区别 , 大写字母是自定义组件
  • 标签必须闭合 如<input>在jsx是非法的
  • 每段JSX中只有一个根节点

属性

和html基本相似

  • class要改为 className
  • style要使用js对象 不能是string 而且key需要使用驼峰写法

如下

在JSX中插入js变量

  • 使用{}可以插入JS变量 函数 表达式
  • 可以插入文本 属性
  • 可以用于注释

代码案例

条件判断

​ 常见的if else 可以通过{}的方式实现,但是在JSX中代码一多就显得不够实用了 以下三种方法可以解决:

  • 使用&&
  • 使用三元表达式
  • 使用函数来判断

比如这样:反之如果flag等于false 就不会出现hello

效果:

三元运算符:flag为判断条件 来控制标签的显示

效果:

函数:

jsx 复制代码
function isShowHello(){
  if (flag)return <p>show hello</p>
  return <p>defaultHello</p>
}

效果 :

循环

  • 使用map来循环
  • 每一个循环项(item)都要有key
  • key需要具有唯一性

实现

jsx 复制代码
const list = [
  {username:'zhangsan', name:"张三"},
  {username:'shuangyue', name:"双月"},
  {username:'lisi', name:"李四"},
]

     {/*循环*/}
        <div>
          {list.map(user=>{
            const {username,name} = user
           return <li key={username}>{name}</li>
          })}
        </div>

效果:

PS : 不建议使用 index 如 :

因为我们的key 需要具有唯一性

小结实战 列表页

开发一个列表页

调整一下显示的jsx

保证这个代码结构简洁 ,然后就可以开始开发了

jsx 复制代码
import React from 'react';
import './App1.css';

function App() {
    const questionList = [
        {id: 'q1', title: '问卷1', isPublished: true},
        {id: 'q2', title: '问卷2', isPublished: true},
        {id: 'q3', title: '问卷3', isPublished: true},
        {id: 'q4', title: '问卷4', isPublished: false}
    ]

    function edit(id) {
        console.log('edit', id);
    }

    return (<div>
        <h1>列表详情页</h1>
        <div>
            {questionList.map(question => {
                const {id, title, isPublished} = question;
                return <div key={id} className="list-item">
                    &nbsp;
                    <strong>{title}</strong>
                    &nbsp;
                    {isPublished ? <span style={{color: "green"}}>已发布</span> : <span>未发布</span>}
                    &nbsp;
                    <button onClick={() => edit(id)}>编辑问卷</button>
                </div>
            })}
        </div>
    </div>)

}

export default App;

css

css 复制代码
.list-item {
    border: 1px solid #ccc;
    padding: 10px;
    margin-bottom: 16px;
    display: flex;
    justify-content: center;
}

效果

组件

react 一切皆是组件

  • 组件拥有一个ui片段
  • 拥有独立的逻辑和显示
  • 可大可小 可以嵌套

组件拆分的价值和意义

  • 组件嵌套来组织的 ui 结构 和 html 一样没有学习成本
  • 良好的拆分组件利于代码维护和多人协同开发
  • 封装公共组件或者直接使用第三方组件复用代码

好的组件化 逻辑是清晰的 更能提升开发效率并且更加的美观易读

我们可以将组件理解成一个一个的函数

使用我们之前的列表页代码 拆分成组件 list1

然后用improt的方式 引入到listdemo中

这样我们的总框架就没有那么多的代码冗余 需要修改对应的代码 只需要寻找对应的组件文件即可

属性 props

  • 组件可以嵌套 有层级关系
  • 父组件可以向子组件传递数据
  • props是只读对象

props 其实就是实现差异化组件信息传递的一种手段

实践

将之前循环内显示数据的div拆出来抽象成组件:QuestCard.tsx 。 CSS还是和之前的内容一样

使用 ts主要是方便传入泛型

QuestCard.tsx

tsx 复制代码
import React, {FC} from "react";
import './QuestCard.css'

type proptype = {
    id: string,
    title: string,
    isPublished: boolean
}
export const QuestCard: FC<proptype> = (props) => {
    const {id, title, isPublished} = props;

    function edit(id) {
        console.log('edit', id);
    }

    return (
        <div key={id} className="list-item">
            &nbsp;
            <strong>{title}</strong>
            &nbsp;
            {isPublished ? <span style={{color: "green"}}>已发布</span> : <span>未发布</span>}
            &nbsp;
            <button onClick={() => edit(id)}>编辑问卷</button>
        </div>)
}

改造list1.jsx 这样就将显示问卷卡片抽取出来为一个独立的组件了

jsx 复制代码
import React from "react";
import './list1.css';
import {QuestCard} from "./QuestCard";

export const List1 = () => {
    const questionList = [
        {id: 'q1', title: '问卷1', isPublished: true},
        {id: 'q2', title: '问卷2', isPublished: true},
        {id: 'q3', title: '问卷3', isPublished: true},
        {id: 'q4', title: '问卷4', isPublished: false}
    ]


    return (
        <div>
            <h1>列表详情页</h1>
            <div>
                {questionList.map(question => {
                    const {id, title, isPublished} = question;
                    return <QuestCard key={id} id={id} title={title} isPublished={isPublished}/>
                })}
            </div>
        </div>)

}

小结:

  • 如何定义和使用组件
  • props-父组件给子组件传递数据
  • 重构列表页 抽象出QuestionCard

效果

children

场景: 当我们把内容签到在子组件标签中时,父组件会自动的在名为 children的prop中接受内容

子组件传递父组件

顾名思义 其实就是子组件给父组件传递信息

tsx 复制代码
function Son({onGetSonMsg}) {
//     son 中的数据
    const sonMsg = 'this is son msg';
    return <div>this is son
        <button onClick={() => onGetSonMsg(sonMsg)}>sendMsg</button>
    </div>
}

function AppDemo() {
    const [msg, setMsg] = useState('')
    const getMsg = (msg) => {
        console.log(msg)
        // msg = '我是信息'  这么改是无效的
        setMsg(msg)
    }
    return <div>
        this is APP Son send msg =>{msg}
        <Son onGetSonMsg={getMsg}/>
    </div>
}
兄弟组件传递

使用状态提升实现兄弟组件通信

  • 其实就是有共同父组件的两个子组件传递信息
  • a 传递给父组件 然后由父组件 传递给 b

代码

tsx 复制代码
import {useState} from "react";

function A({onGetAName}) {
    const name = "a name"
    return <div>this is A
        <button onClick={() => onGetAName(name)}>send</button>
    </div>
}

function B({pushAName}) {
    return <div>this is B
        {pushAName}
    </div>
}

function AppDemo() {
    const [aName, setAName] = useState('');
    const getAName = (name) => {
        console.log(name)
        setAName(name)
    }
    return <div>
        this is app
        <A onGetAName={getAName}/>
        <B pushAName={aName}/>
    </div>
}


export default AppDemo;
function A({onGetAName}) {
    const name = "a name"
    return <div>this is A
        <button onClick={() => onGetAName(name)}>send</button>
    </div>
}

function B({pushAName}) {
    return <div>this is B
        {pushAName}
    </div>
}

function AppDemo() {
    const [aName, setAName] = useState('');
    const getAName = (name) => {
        console.log(name)
        setAName(name)
    }
    return <div>
        this is app
        <A onGetAName={getAName}/>
        <B pushAName={aName}/>
    </div>
}

效果

HOOKS

useState

这是React 中的一个hook 函数 它允许我们向组件添加一个状态变脸,从而控制组件的渲染结果

tsx 复制代码
 const [msg, setMsg] = useState('')
  1. useState是一个函数 返回值是一个数组
  2. 数组中的第一个参数是状态变量,第二个参数是set函数用于修改状态
  3. useState的参数将作为状态变量的初始值

修改规则

在React 中 状态被认为是只读的 我们应该替换而不是修改 直接修改状态不会得到视图的更新

tsx 复制代码
    const [msg, setMsg] = useState('')
    const getMsg = (msg) => {
        console.log(msg)
        // msg = '我是信息'  这么改是无效的
        setMsg(msg)
    }
    
    //如果是对象作为参数
      const [msg, setMsg] = useState({id:'122ds'})
    const getMsg = (msg) => {
        console.log(msg)
        // msg = '我是信息'  这么改是无效的
        setMsg({
            ...msg,
        	id:'123'})
    }

useContext 组件通信

  1. 使用createContext 方法创建一个上下文对象 ctx=
  2. 在顶层组件 app 中 通过 ctx.Provider提供数据
  3. 在底层组件 通过 useContext钩子函数获取消费数据

案例 :

我们需要将app的消息传递到b

TSX 复制代码
const MsgContext = createContext()

function A() {
    return <div>this is A
        <B/>
    </div>
}

function B() {
    const msg = useContext(MsgContext)
    return <div>this is B from APP:{msg}
    </div>
}

function AppDemo() {
    const msg = "this is app msg"
    return (<div>
        <MsgContext.Provider value={msg}>
            this is app
            <A/>
        </MsgContext.Provider>
    </div>)
}

useEffect

这是React中的一个 hook 函数 ,用于在React 中创建不是由事件引起而是由渲染本身引起的操作,比如发送 AJAX请求 更改DOM等

基础使用

需求: 在组件渲染完毕后,从服务器获得列表数据展示

语法:

TSX 复制代码
useEffect(()=>{},[])
  1. 参数1是一个函数,可以把它叫做副作用函数,函数内部可以放置要执行的操作
  2. 参数2是一个数组 ,数组里放置依赖项,不同依赖项会影响第一个参数的执行,当该参数是一个空数组的时候,副作用函数只会在组件渲染完毕后执行一次
tsx 复制代码
import {useEffect, useState} from "react";

const URL = 'http://geek.itheima.net/v1_0/channels'

function AppDemo() {
    const [list, setList] = useState([]);
    useEffect(() => {
        async function getList() {
            const res = await fetch(URL)
            const jsonRes = await res.json()
            console.log(jsonRes)
            setList(jsonRes.data.channels)
        }

        getList()
        console.log("list", list)
    }, []);
    return (<div>
        this is app
        <ul>
            {list.map(item => <li key={item.id}>{item.name}</li>)}
        </ul>
    </div>)
}


export default AppDemo;

效果

依赖项参数

TSX 复制代码
function AppDemo() {
    /*1. 没有依赖项*/
    const [count, setCount] = useState(0);
    // useEffect(() => {
    //     console.log("副作用函数执行了")
    // });
    /*2 传入空数组依赖*/
    // useEffect(() => {
    //     console.log("副作用函数执行了")
    // }, []);
    useEffect(() => {
        console.log("副作用函数执行了")
    }, [count]);
    return <div>this is app
        <button onClick={() => setCount(count + 1)}>+{count}</button>
    </div>
}

清除副作用

useEffect中编写的由渲染本身引起的对接组件外部的操作,社区也经常把它叫做副作用操作,我们想在组件卸载时把这个定时器清理掉,这个过程就是清理副作用

tsx 复制代码
import {useEffect, useState} from "react";

function Son() {
    useEffect(() => {
        const timer = setInterval(() => {
            console.log("定时器执行中...")
        }, 1000)
        return () => {
            //     清楚副作用
            clearInterval(timer)
        }
    }, []);
    return <div>this is son</div>
}

function AppDemo() {
    const [show, setShow] = useState(true)
    return <div>this is app
        {show && <Son/>}
        <button onClick={() => setShow(false)}>卸载组件</button>
    </div>
}

export default AppDemo;

自定义hook

暂时没有什么很好的例子 写一个比较简单的 之后再拓展

tsx 复制代码
import {useState} from "react";

function useToggle() {
// 可复用代码
    const [value, setValue] = useState(true);
    const toggle = () => {
        setValue(!value)
    }
    return {value, toggle}
}

function AppDemo() {
    const {value, toggle} = useToggle()
    return <div>this is app
        {value && <div>this is show Toggle</div>}
        <button onClick={toggle}>Toggle</button>
    </div>
}

export default AppDemo;

效果

点击

相关推荐
最新资讯动态5 分钟前
DialogHub上线OpenHarmony开源社区,高效开发鸿蒙应用弹窗
前端
淬渊阁6 分钟前
汇编学习之《扩展指令指针寄存器》
汇编·学习
lalapanda7 分钟前
UE5学习记录part12
学习·ue5
lvbb6614 分钟前
框架修改思路
前端·javascript·vue.js
树上有只程序猿16 分钟前
Java程序员需要掌握的技术
前端
从零开始学安卓19 分钟前
Kotlin(三) 协程
前端
阿镇吃橙子23 分钟前
一些手写及业务场景处理问题汇总
前端·算法·面试
庸俗今天不摸鱼24 分钟前
【万字总结】前端全方位性能优化指南(九)——FSP(First Screen Paint)像素级分析、RUM+合成监控、Lighthouse CI
前端·性能优化
逆袭的小黄鸭24 分钟前
JavaScript:作用域与作用域链的底层逻辑
前端·javascript·面试