0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

总结版2

Posted at

一:受控表单绑定

通过react状态去控制Input框的状态
image.png
监听输入框内容变化,每当用户输入时,e.target.value(输入框的值)会更新 value,从而实现输入框内容与状态同步。

import {useState} from "react"
// 1.准备一个React状态值
const [value,setValue] = useState("")
// 2.通过value属性绑定状态,通过onChange属性绑定状态同步的函数
// 通过事件参数e拿到输入框的最新的值,反向修改到react状态身上
<input
  type="text"
  value={value}
  onChange={(e) => setValue(e.target.value)}
/>

二:react中获取dom(使用useRef)

使用useRef获取input输入框的DOM对象
①1.useRef生成ref对象,并与JSX绑定
②2.dom可用时,通过inputRef.current拿到dom对象

import {useRef} from "react";

function App(){
   // 1. 创建一个 ref 对象,并初始化为 null
   const inputRef = useRef(null)

   // 2. 定义一个函数,点击按钮时获取 input 的 DOM 对象
   const showDom =()=>{
      console.log(inputRef.current)  // 输出 input 的 DOM 对象
   }
   return(
     <div>
        {/* 3. 绑定 ref 到 input 元素 */}
       <input type="text" ref={inputRef} />
        {/* 4. 点击按钮时执行 showDom 函数 */}
       <button onClick={showDom}>获取dom</button>
     </div>
   )
}

三:案例-发表评论

1.核心功能实现

①用数控绑定方式,可以把用户输入的东西,收集到content里面
②点击时发布评论,替换content字段,收集到的数据是什么就绑定什么
③延续数据修改不可变的方式,原本的所有数据都展开,增加一条自己的数据
※需求:获取评论内容,点击发布按钮发布评论
⭐setCommentList([...commentList, newComment]):
...commentList 复制已有的评论列表。
{...} 创建一个新评论对象,并添加到列表中。
setCommentList() 更新 commentList 状态,让页面重新渲染,显示新评论。

 // 发表评论
const [content,setContent] = useState("")
const handPublish =()=>{
  setCommentList([
      ...commentList,
      {
         rpid:100,
         user:{
            uid:"30009257",
            avatar,
            uname:"黑马前端",
         },
         content:content,
         ctime:"10-19 09:00",
         like:66,
         }
  ])
}
// 评论框
<textarea
    className="reply-box-textarea"
    placeholder="发一条友善的评论"
    value={content}
    onChange={(e)=>setContent(e.target.value)}
/>
// 发布按钮
<div className="reply-box-send">
   <div className="send-text" onClick={handPublish}>发布</div>
</div>   

2.id和时间处理

需求:rpid要求一个唯一的随机数id(uuid)
ctime要求以当前时间为标准,生成固定格式(dayjs)

// 安装uuid
npm install uuid
// 使用方式
 import {v4 as uuidv4} from "uuid";
 uuidv4();

 // 安装Day.js
 npm install dayjs
 // 使用方式
 import dayjs from "dayjs"
 Format
{
import {v4 as uuidV4} from "uuid"
import dayjs from "dayjs"
         rpid:uuidV4(), //随机id
         user:{
            uid:"30009257",
            avatar,
            uname:"黑马前端",
         },
         content:content,
         ctime:dayjs(new Date()).format("MM-DD hh:mm"),// 格式化 月-日 时:分
         like:66,
         }

3.清空内容和聚焦实现

image.png
需求:清空内容-把控制input框的value状态设置为空串
重新聚焦-拿到input的dom元素,调用focus方法
inputRef.current.focus() 让输入框自动获取焦点

// 1.清空输入框内容
setContent("")
// 2.重新聚焦 dom(useRef) -focus
const inputRef = useRef(null)
inputRef.current.focus()
// 评论框
<textarea
    className="reply-box-textarea"
    placeholder="发一条友善的评论"
    ref={inputRef}
    value={content}
    onChange={(e)=>setContent(e.target.value)}
/>    

四:父子组件通信

组件之间的数据传递

1.父传子基础实现

步骤:①父组件传递数据-在子组件标签上绑定属性
②子组件接收数据-子组件通过props参数接收数据
props:包含着父组件传递过来的所有数据
父组件App通过props向子组件Son传递数据,然后子组件Son在渲染时接收并显示这个数据。

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

function App(){
   const  name = "this is app name"
   return(
      <div>
        <Son name = {name}/>  {/* 传递name变量给Son组件 */}
      </div>
   )
} 

2.props说明

可以传递任意的数据:数字,字符串,布尔值,数组,对象,函数,jsx
props是只读对象,子组件只能读取props中的数据,不能直接进行修改,父组件的数据只能有父组件修改

3.父传子children说明

父组件通过children传递子元素给Son组件,然后Son组件可以通过 props.children渲染这个子元素。
props.children:Son组件的子元素

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

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

4.子传父实现

在子组件中调用父组件中的函数并传递实参
父组件通过props传递一个函数getMsg给子组件,然后子组件在点击按钮时调用这个函数,并把自己的数据sonMsg传回给父组件。

function Son({onGetSonMsg}){
   // Son组件中的数据
   const sonMsg = "this is son msg"
   return(
      <div>
        this is Son
        <button onClick ={()=>onGetSonMsg(sonMsg)}>sendMsg</button>
      </div>
   ) 
}

function App(){
  const [msg,setMsg] = useState("")
  const getMsg = (msg)=>{
    console.log(msg)
    setMsg(msg)
  }
   return(
      <div>
          this is App,{msg}
         <Son onGetSonMsg = {getMsg}/>
      </div>
   )
}    

五:useEffect

1.概念理解和基础使用

用来执行一些“自动触发的操作”,而不是等到用户点击按钮、输入内容等事件才执行。可以想象成一个“自动运行的代码块”:当组件加载(渲染)时,就会自动执useEffect里的代码,当某些数据变化时(比如 state 发生变化),useEffect也可以自动执行。
useEffect 不需要用户手动触发(比如点击按钮),它会在页面加载或状态变化时自动执行。比如:页面一打开就执行代码,或某个状态变化后自动执行代码
你只管写在useEffect里,React会帮你找合适的时机自动执行!

useEffect(() =>{},[])
// 参数1是一个函数,在函数内部可以放置要执行的操作
// 参数2是一个数组,在数组里放置依赖项,不同依赖项会影响第一个参数函数的执行,
//                 当是一个空数组的时候,只会在组件组件首次渲染时执行一次
    

⭐作用
①首次进入页面后,初始化操作
②监视某个值的变化
③退出页面后,执行收尾操作

2.不同依赖项说明

①空数组依赖:只在初始渲染时执行一次

import { useEffect, useState } from "react";

function App() {
  // 2.传入空数组依赖  初始执行一次
  useEffect(()=>{
    console.log("副作用函数执行了")
  },[])
  return (
    <div>
         this is App
         <button onClick ={()=>setCount(count +1)}>+{count}</button>
    </div>
  )
}
export default App; 

②添加特定依赖项:组件初始渲染+特性依赖项变化时执行

import { useEffect, useState } from "react";

function App() {
  const [count,setCount] = useState(0)
  // 3.传入特定依赖项  初始 + 依赖项变化时执行
  useEffect(()=>{
    console.log("副作用函数执行了")
  },[count])
  return (
    <div>
         this is App
         <button onClick ={()=>setCount(count +1)}>+{count}</button>
    </div>
  )
}
export default App;    

3.清除副作用

在useEffect里,“副作用”指的是组件渲染时需要执行的额外操作,比如:
发送网络请求,操作 DOM,订阅事件,定时器。这些操作不是组件渲染UI所必需的,但又是程序运行时需要的,所以叫“副作用”。
React提供了清理副作用的方法,就是在useEffect里返回一个函数,这个函数会在组件卸载或useEffect重新执行时运行,负责清除不需要的副作用。
useEffect是“开灯”,但如果灯一直亮着没人关,就会浪费电。所以React允许你在组件卸载时“关灯”,就是清除副作用!

 useEffect(() =>{
    // 实现副作用操作逻辑
    return()=>{
    // 清除副作用逻辑
    }
 },[])  

在Son组件渲染时开启一个定时器,卸载时清除这个定时器
①Son 组件在渲染时启动一个定时器,每隔 1 秒输出 "定时器执行中"。
②App 组件包含一个 show 状态,控制 Son 组件是否显示。
③点击按钮 setShow(false) 会卸载 Son 组件,同时 useEffect 清理定时器,防止定时器继续运行。

import { useEffect, useState } from "react";

function Son(){
  // 1.渲染时开启一个定时器
  useEffect(()=>{
     const timer = setInterval(()=>{
      console.log("定时器执行中")
     },1000)

     return () =>{
      // 清除副作用 组件卸载时
      clearInterval(timer)
     }
  },[])
  return <div>this is son</div>
}

function App() {
  // 通过条件渲染模拟组件卸载
  const [show,setShow] = useState(true)
  return (
    <div>
         {show && <Son />}
         <button onClick ={()=>setShow(false)}>卸载Son组件</button>
    </div>
  )
}
export default App;   

六:自定义hook实现

useToggle是一个自定义Hook,用于管理 true/false 状态。
好处是让toggle逻辑可以复用,多个组件可以直接使用。
按钮点击时,toggle() 切换 value,从而控制

显示/隐藏。
import { useEffect, useState } from "react";

// 封装自定义hook

// 1.声明一个以use打头的函数
// 2.在函数体内封装可复用的逻辑 只要是可复用的逻辑
// 3.把组件中用到的状态或者回调return出去 以对象或者数组
// 4.在哪个组件中要用到这个逻辑,就执行这个函数,解构出来状态和回调进行使用
function useToggle(){
  // 可复用的逻辑代码
  const [value,setValue] = useState(true)
  const toggle = ()=>setValue(!value)

  // 哪些状态和回调函数需要在其他组件中使用 return
  return{
    value,
    toggle
  }
}

function App() {
  const {value, toggle} = useToggle()
  return (
    <div>
        {value && <div>this is div</div>}
         <button onClick ={toggle}>toggle</button>
    </div>
  )
}
export default App;    

七:reacthooks使用规则说明

1.只能在组件中或者其他自定义hook函数中调用
2.只能在组件的顶层调用,不能嵌套在if for其他函数中

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?