react学习(一)

一. React 创建命令

  1. 官方推荐:Vite 创建(最快、最现代)

npm create vite@latest

  1. 传统方式:Create React App(CRA)老项目常用,配置简单、生态成熟

npx create-react-app my-react-app

二. jsx

概念: jsx 是js和xml(html) 的缩写,表示在js代码中编写html模版结构,它是react中编写ui模版的方式

javascript 复制代码
const message='this is message'
function App(){
  return (
    <div>
      <h1> this is title </h1>
      {message}
    </div>
  )
}

优势:

  1. html的声明式模版写法 2. js的可编程能力

2.1 jsx本质

jsx 并不是标准的js语法,它是js的语法扩展,浏览器本身不能识别,需要通过解析工具做解析之后才能在浏览器中运行

2.2 jsx中使用js表达式

在jsx中可以通过大括号语法{ } 识别js中的表达式,比如常见的变量,函数调用,方法调用等等

  1. 使用引号传递字符串

  2. 使用js变量

  3. 函数调用和方法调用

  4. 使用 js对象

javascript 复制代码
function getName(){
  console.log(111)
  return '我是名字'  
}
const count='111'
function App() {
  return (
    <div>
       {/* 用引号传递字符串 */}
       {'this is message'}
       {/* 识别js 变量 */}
       {count}
       {/* 函数调用 */}
       {getName()}
       {/* 方法调用 */}
       {new Date().getDate()}
       {/* 使用js对象 */}
       <div style={{color:'red'}}>this is div</div>

    </div>
  )
}
export default App

注意: if 语句,switch 语句,变量声明属于语句,不是表达式,不能出现在{ } 中

2.3 jsx 使用列表渲染

javascript 复制代码
const list = [
  { id: 1, name: '第一条数据' },
  { id: 2, name: '第二条数据' },
  { id: 3, name: '第三条数据' }
]

function App() {
  return (
    // 渲染列表
    // map 循环哪个结构 就return 哪个结构
    // 注意事项: 加上一个独一无二的key 字符串或者number id 
    // key的作用: react框架内部使用 提升更新性能的 
    <ul>
      {list.map(item=><li key={item.id}>{item.name}</li>)}
    </ul>
  )
}

2.4 实现基础条件渲染

javascript 复制代码
const isLogin = true 
function App() {
  return (
    <div className="App">
      逻辑与 && 
      {isLogin && <span>aaa</span>}
      三元运算 
      {isLogin? <span>sdklaj </span>:<span></span>}
    </div>
  )
}

2.5 实现复杂条件渲染

javascript 复制代码
// 根据文章不同渲染不同的div
const type = 1 

function getType() {
  if (type === 1) {
    return <div>萨迪克辣椒</div>
  } else if (type === 2) {
    return <div>文章类型2</div>
  } else if (type === 3) {
    return <div>文章类型3</div>
  } else {
    return <div>未知类型</div>
  }
}

function App() {
  return (
    <div className="App">
      {getType()}      
    </div>
  )
}

export default App

2.6 点击事件

javascript 复制代码
// const handleClick=()=>{
//   console.log('button按钮被点击了')
// }
//事件参数e 
// const handleClick=(e)=>{
//   console.log('button按钮被点击了',e)
// }

// //传递自定义参数
// const handleClick=(name)=>{
//   console.log('button按钮被点击了',name)
// }
//自定义参数 +  事件对象e 
const handleClick=(name,e)=>{
  console.log('button按钮被点击了',e)
}
  

function App() {
  return (
    <div className="App">
            <button onClick={(e)=>handleClick('jack',e)}>click me</button>
    </div>
  )
}

三. 组件

3.1 在React中,一个组件就是首字母大写的函数,内部存放了组件的逻辑和视图UI,渲染组件只需要把组件当成标签书写即可

javascript 复制代码
//定义组件
const Button =()=>{
   //业务逻辑组件逻辑 
   return <button>click me!</button>
}
function App() {
  return (
    <div className="App">
       {/* 使用组件(渲染组件) */}
       {/* 自闭和 */}
       <Button/>
       {/* 成对标签  */}
       <Button></Button>  
    </div>
  )
}
export default App

四. useState 基础使用

useState 是一个React Hook(函数),它允许我们向组件添加一个状态变量,从而控制影响组件的渲染结果

count = 0 ===> 0

count = 1 ===> 1

本质: 和普通JS变量不同的是,状态变量一旦发生变化组件的视图UI也会跟着变化(数据驱动视图)

javascript 复制代码
const [count,setCount] = useState(0)
  1. useState 是一个函数,返回值是一个数组

  2. 数组中第一个参数是状态变量,第二个参数是set函数用来修改状态变量

  3. useState的参数将作为count的初始值

4.1 用useState 实现一个计数器

javascript 复制代码
// useState 实现一个计数器按钮
import { useState }  from 'react'
function App() {
        //1. 调用useState 添加一个状态变量
     //count 状态变量
     //setCount 修改状态变量的方法
     
     const [count,setCount] =useState(0)

     //2. 点击事件回调
     const handleClick=()=>{
       // 作用: 1. 用传入的新值修改count 
       //2. 重新使用心得count渲染UI 
       setCount(count + 1)
     }
  return (
     <div> <button onClick={handleClick}></button>{count}</div>
  )
}
export default App

4.2 状态不可变

在React中,状态被认为是只读的,我们应该始终替换它而不是修改它,直接修改状态不能引发视图更新

  1. 直接修改 无法引发视图更新
javascript 复制代码
let [count,setCount] = useState(0)

const handleClick=()=>{
 
  //直接修改 无法引发视图更新
  count ++ 
  console.log(count)
}
  1. 用传入的新值修改count, 重新使用新的count渲染UI
javascript 复制代码
const handleClick=()=>{
   setCount(count + 1)
}

4.3 修改对象状态

对于对象类型的状态变量,应该使用传给set方法一个全新的对象来进行修改

  1. 直接修改原对象,不引发视图变化
javascript 复制代码
//直接修改原对象,不引发视图变化
const [form,setForm] = useState({
  name: 'jack',
})

const handleChangeName=()=>{
  form.name='john'
}
  1. 调用set传入新对象用于修改
javascript 复制代码
const [form,setForm] = useState({
  name: 'jack',
})

const handleChangeName=()=>{
  setForm({
    ...form,
    name:'john'
  })
}

五. 基础样式控制

5.1 行内样式style

javascript 复制代码
function App() {
  return (
     <div style={{
        color:"red",
        fontSize:'20px',
        backgroundColor:"#f5f5f5",
        padding: '10px'
     }}> 
      行内样式
     </div>
  )
}

5.2. 在组件中导入使用

javascript 复制代码
import './App.css'

function App(){
   return <div className='box'>外部 CSS 样式 </div>
}

注意: React 用className 代替class

5.3 动态className

.active {

color: red;

font-weight: bold;

}

javascript 复制代码
import {useState} from 'react'
import './App.css'


function App(){
  const [active,setActive] = useState(false)
  return(
   <div className={active ? 'active' :''} onClick={()=>setActive(!active)}>
   点击切换类名
   </div>
  )
}

5.4 多个class 拼接(常用)

javascript 复制代码
// 普通写法

<div className={`box ${active ? 'active' : ''}`}}>

//或者用classnames 库 

import classNames from 'classnames'

<div className = {classNames('box',{active:active})}>

六. 案例

6.1 评论列表渲染

javascript 复制代码
import { useState } from "react";
import "./App.css";
import _ from 'lodash';

const list = [
  {
    rpid: 1,
    user: {
      avatar: 'sxxxx',
      uid: '30009257',
      uname: 'react'
    },
    content: '哇,这个组件写得太丝滑了!学到了!',
    ctime: '04-14 10:30:25',
    like: 256
  },
  {
    rpid: 2,
    user: {
      uid: '13258166',
      avatar: 'http://toutiao.itheima.net/resources/images/avatar2.jpg',
      uname: 'Vue'
    },
    content: '确实不错,不过Vue的写法也很优雅,各有千秋~',
    ctime: '04-14 09:45:10',
    like: 188
  },
  {
    rpid: 3,
    user: {
      uid: '13258167',
      avatar: 'http://toutiao.itheima.net/resources/images/avatar3.jpg',
      uname: 'TypeScript'
    },
    content: '建议加上严格模式,不然大型项目容易出Bug🤣',
    ctime: '04-14 08:20:05',
    like: 99
  },
  {
    rpid: 4,
    user: {
      uid: '13258168',
      avatar: 'http://toutiao.itheima.net/resources/images/avatar4.jpg',
      uname: '前端老码农'
    },
    content: '点赞!这种业务场景的实战讲解最接地气了!',
    ctime: '04-14 07:15:30',
    like: 120
  },
  {
    rpid: 5,
    user: {
      uid: '13258169',
      avatar: 'http://toutiao.itheima.net/resources/images/avatar5.jpg',
      uname: 'uni-app开发者'
    },
    content: '大佬什么时候出一期跨端兼容的教程?坐等!🚀',
    ctime: '04-14 06:05:45',
    like: 210
  }
];

// 当前登录用户
const user = {
  uid: '30009257',
  avatar: 'sxxxx',
  uname: 'react'
};

// 导航 Tab
const tabs = [
  { type: "hot", text: "最热" },
  { type: 'time', text: '最新' }
];

function App() {
  const [commentList, setCommentList] = useState(_.orderBy(list, 'like', 'desc'));
  const [activeType, setActiveType] = useState('hot');

  // 删除功能
  const handleDel = (id) => {
    setCommentList(commentList.filter(item => item.rpid !== id));
  };

  // 切换排序
  const handleTabChange = (type) => {
    setActiveType(type);
    if (type === 'hot') {
      setCommentList(_.orderBy(commentList, 'like', 'desc'));
    } else {
      setCommentList(_.orderBy(commentList, 'ctime', 'desc'));
    }
  };

  return (
    <div className="app">
      {/* 顶部导航 */}
      <div className="title">
        <div>评论</div>
        <div className="nav">
          {tabs.map(item => (
            <span
              key={item.type}
              onClick={() => handleTabChange(item.type)}
              className={`nav-item ${activeType === item.type ? 'active' : ''}`}
            >
              {item.text}
            </span>
          ))}
        </div>
      </div>

      {/* 评论列表 */}
      <div className="body">
        {commentList.map(item => (
          <div className="comment-item" key={item.rpid}>
            <div className="uname">{item.user.uname}</div>
            <div className="content">{item.content}</div>
            <div className="time">{item.ctime}</div>
            
            {/* 仅自己显示删除按钮 */}
            {user.uid === item.user.uid && (
              <span className="del" onClick={() => handleDel(item.rpid)}>
                删除
              </span>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}

export default App;

七. 表单

7.1 受控绑定表单

受控表单=表单元素的value 完全由React状态(state)控制

  • 输入框显示什么 - > 看value
  • 输入框变了 -> 触发 onChange -> 更新state
  • 数据由React全权管理
javascript 复制代码
// 1. 用 state 管理数据
const [value, setValue] = useState('')

// 2. value 绑定 state
// 3. onChange 更新 state
<input 
  type='text' 
  value={value} 
  onChange={(e)=>setValue(e.target.value)} 
/>

7.2 非受控表单

非受控表单=表单自己管自己,React 不控制

  • 数据存在DOM里
  • 用useRef 获取值
  • 不用state, 不用onChange
javascript 复制代码
import {useRef} from "react";
// React 中获取dom 
// 1. useRef生成ref对象 ,绑定到dom标签身上
// 2. dom可用时,ref.current 获取dom 
// 渲染完毕之后dom生成之后才可用
function App() {
  const inputRef = useRef(null)
  const showDom=()=>{
    console.dir(inputRef.current)
  }
  return (
    <div>
      <input type='text' ref={inputRef} />
      <button onClick={showDom}>获取dom</button>
    </div>
  );
}

export default App;

八. 评论案例

javascript 复制代码
import { useState, useRef } from 'react'

const list = [{
  id: 1,
  content:'sss'
}]

function App() {
  const [commentList, setCommentList] = useState(list)
  const [content, setValue] = useState('')
  const inputRef = useRef(null)

  const publish = () => {
    if (!content.trim()) return

    setCommentList([
      ...commentList,
      {
        id: Date.now(),
        content: content
      }
    ])

    setValue('')
    inputRef.current?.focus() // 加了安全调用
  }

  return (
    <div>
      <input
        type='text'
        value={content}
        onChange={(e) => setValue(e.target.value)}
        ref={inputRef}
      />
      <button onClick={publish}>发表评论</button>

      <div style={{ marginTop: 20 }}>
        {commentList.map(item => (
          <div key={item.id} style={{ padding: '8px 0' }}>
            {item.content}
          </div>
        ))}
      </div>
    </div>
  )
}

export default App
相关推荐
Cobyte1 小时前
5.响应式系统比对:手写 React 响应式状态库 Mobx
前端·javascript·vue.js
鹓于1 小时前
PPT VBA随机选题系统实现详解
java·前端·javascript
Darkershadow2 小时前
蓝牙学习之通过OP CODE解析输入输出数据
学习·蓝牙·ble·mesh
m0_716765232 小时前
数据结构--栈的插入、删除、查找详解
开发语言·数据结构·c++·经验分享·学习·青少年编程·visual studio
qq_12084093712 小时前
Three.js 模型加载与线上稳定性实战:路径、跨域、缓存与降级全链路指南
开发语言·javascript·缓存·vue3
江苏世纪龙科技2 小时前
【世纪龙科技】给智能网联汽车教学装上一个“数字副驾”
学习
invicinble2 小时前
对于学习视频的技巧
学习
qq_12084093712 小时前
Vue3 + Three.js 实战入门:从零搭建可交互3D场景(含模型加载与性能优化)
javascript·3d·vue3·交互
承渊政道2 小时前
【递归、搜索与回溯算法】(二叉树深搜模型拆解与经典题型全面突破)
数据结构·c++·学习·算法·leetcode·macos·bfs