React 18 开发备忘录

React 18 开发备忘录

记录 React18 环境下基础功能与常用 hook ,用于备查。

开发环境

node V20
React V18

JSX

在JS中使用HTML模板结构

function App() {
  return (
    <div classname="App">
      this is App
    </div>
  )
}
export default App

列表渲染

数据循环渲染

const list = [
  { id: 1, name: 'Vue' },
  { id: 2, name: 'React' },
  { id: 3, name: 'Uni-app' }
]

function App() {
  return (
    <div classname="App">
      {/* 列表渲染 */} 
      <ul>
        { list.map(el => (
          <li key={el.id}>{el.name}</li>
        )) }
      </ul>
    </div>
  )
}
export default App

条件渲染

基础条件渲染
通过标识符逻辑判断是否渲染 html 模板

let flag = true
let loading = false

function App() {
  return (
    <div classname="App">
      {/* 条件渲染 */} 
      {flag && <span>render</span>}
      {loading ? <span>loading...</span> : <span>render</span>}
    </div>
  )
}
export default App

复杂条件渲染

通过函数与标识符判断需要渲染的 HTML 模板

const flag = 1

function getTemplate() {
  if(flag === 0) {
    return <div>0</div>
  } else if (flag === 1) {
    return <div>1</div>
  } else {
    return <div>2</div>
  }
}

function App() {
  return (
    <div classname="App">
      {/* 复杂条件渲染 */} 
      { getTemplate() }
    </div>
  )
}
export default App

事件绑定

元素上通过 on 绑定事件

function App() {
  const handleClick = () => {
    console.log('click')
  }
  return (
    <button onClick={handleClick}>click</button>
  )
}

组件基础使用

函数作为渲染组件时函数名首位大写

const Button = () => {
  return <button>click</button>
}

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

基础样式控制

● 原始样式控制: 通过模板字符串逻辑判断渲染需要的样式类
● 通过 classnames 类优化库渲染

.title-row {
	background: grey;
}
.actived {
  color: #ff0036;
}
import './app.css'
import classNames from 'classnames'

function App() {
  let flag = true
  return (
    <div className="App">
      {/* 基础控制 */}
      <div className={`title-row ${flag && 'actived'}`}>
        hello!
      </div>
      {/* 通过classnames 优化类名控制 */}
    	<div 
    		className={classNames('title-row', 'actived': flag)}
    	>
        hello!
      </div>
    </div>
  ) 
}
export default App

React Hook

useState

● useState 是一个函数, 返回值是一个数组.
● 数组中的第一个参数是状态, 第二个参数是用来修改状态默认状态首位大写并加前缀set, 如下所示 title 与 setTitle.
● useState的参数作为状态的初始值.

import { useState } from 'react'

function App() {
  {/* 基础类型的设置与修改 */}
  let [title, setTitle] = useState('hello')
  const handleClick = () => {
    setTitle('title is change')
  }
	{/* 对象类型的设置与修改 通过结构与属性覆盖 */}
  let [form, setForm] = useState({ name: 'liump' })
  function handleChangeForm() {
    setForm({
      ...form,
      name: 'mpliu'
    })  
  }
  
  return (
    <div onClick={handleClick}>
      { title }
    </div>
  )
}

useEffect

场景: 在组件渲染完毕之后,立即从服务端获取数据并显示到页面中
● 参数1是一个函数, 可以把它叫做副作用函数, 在函数内部可以放置要执行的操作.
● 参数2是一个数组, 在数组里放置依赖项, 不同依赖项会影响第一个参数函数的执行, 如果是空数据, 副作用函数只会在组件渲染完毕后之后执行一次

import {useEffect} from 'react'
useEffect(
  () => {
    
  }, 
  []
)

副作用清除, 例如销毁定时器

import {useEffect} from 'react'
useEffect(() => {
  const timer = setInterval(() => {
    console.log('setInterval')
  }, 1000)

  return () => {
    clearInterval(timer)
  }
},[])

useMemo

在组件每次重新渲染的时候缓存计算结果

import { useState, useMemo } from 'react'

function fib (n) {
  console.log('计算函数执行了')
  if(n<3) return 1
  return fib(n-2) + fib(n-1)
}

function App() {
  const [count1, setCount1] = useState(0)
  
  const result = useMemo(()=>{
    return fib(count1)
  }, [count1])
  
  const [count2, setCount2] = useState(0)
  console.log('组件重新渲染了')
  return (
    <div className="App">
      this is app
      <button onClick={() => setCount1(count1 + 1)}>
        change count1: {count1}
      </button>
      <button onClick={() => setCount2(count2 + 1)}>
        change count2: {count2}
      </button>
    </div>
  )
}

export default App

useRef

what? 获取 DOM 的 hook
why?需要获取 DOM 并操作
where?函数组件中通过 useRef
how?
● 通过 useRef 申明状态
● 在元素上通过 ref 与申明的状态名绑定

import { useRef } from 'react'

function App() {
  const inputRef = useRef(null)
  const inputDom = () => {
    console.dir(inputRef.current)
  }
  return (
    <div className="App">
      <input
        type="text"
        ref={inputRef}
      ></input>
      <button onClick={inputDom}>
        获取DOM
      </button>
    </div>
  )
}

useNavigate

react-router-dom 路由跳转 hook

import { useNavigate } from 'react-router-dom'
  
const navigate = useNavigate()
const handleToDetail = (id: string) => {
  // 路由跳转
  navigate('/home?id='+id)
}
useSearchParame
react-router-dom 获取路由参数hook
// 路由带参调整
navigate('/article?id=1001&name=jack')

// 获取路由参数 hook
const [params] = useSearchParams()
let id = params.get('id')

受控表单绑定

● 通过 value 绑定状态
● 通过 on 事件触发变更状态

import {useState} from 'react'
function App() {
  let [userName, setUserName] = useState('')
  const handleChangeUserName = (e) {
    setUserName(e.target.value)
  }
	return (
    <div className="App">
      <input 
        value={userName}
        onChange={handleChangeUserName}
      />
    </div>
  )
}
export default App

组件通信

父传子

● props 可传递任意的数据(数字、字符串、布尔值、数组、对象、函数、JSX)
● props 是只读对象(父组件的数据只能由父组件修改)

<Son
  name={appName}
  age={20}
  isTrue={false}
  list={['React', 'axios']}
  obj={{name: 'liump'}}
  cb={ () => console.log('callback')}
  child={ <span>child</span> }
></Son>

props 接收的属性

props
	age: 20
	cb: f cb() {}
	child: <span/>
	isTrue: false
	list: ["React", "axios"]
	name: "this is app name"
	obj: {name: "liump"}

例如

function Son(props) {
  console.log(props)
  return <div>this is son, {props.name}, jsx: {props.child}</div>
}

function App() {
  const name = "this is app name"
  return (
    <div>
      <Son
        name={name}
        age={20}
        isTrue={false}
        list={['React', 'axios']}
        obj={{name: 'liump'}}
        cb={ () => console.log('callback')}
        child={ <span>child</span> }
      ></Son>
    </div>
  ) 
}
export default App

父传子-children

场景: 当我们把内容嵌套在子组件标签中时, 父组件会自动在名为 children 的 prop 属性中接收该内容

function Son(props) {
  console.log(props)
  return <div>this is son, {props.children}</div>
}

function App() {
  return(
    <div>
      <Son>
        <span>this is span</span>
      </Son>
    </div>
  )
}
export default App

子传父

function Son({onGetMsg}) {
  const sonMsg = 'this is son msg'
  return (
    <div>
      this is Son
      <button onClick={() => onGetMsg(sonMsg)}>
        sendMsg
      </button>
    </div>
  )
}

function App() {
  const getMsg = (msg) => {
    console.log(msg)
  }
  return (
    <div>
      this is App
      <Son onGetMsg={getMsg}/>
    </div>
  )
}

export default App

兄弟组件通信

通过共同的父组件传递消息
● A组件先通过子传父的方式把数据传给父组件App
● App拿到数据后通过父传子的方式再传递给B组件

import {useState} from 'react'

function A({getAName}){
  const name = 'this is A name'
  return (
    <div>
      this is A component,
      <button onClick={() => getAName(name)}>send</button>
    </div>
  )
}

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

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

export default App
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值