受控表单绑定、React获取Dom\组件通信、useEffect、自定义hook函数和ReactHooks使用规则
- 一、受控表单绑定
- 1.准备React状态值
- 2.通过value属性绑定状态,通过onChange属性绑定状态同步的函数
- 二、React中获取DOM
- 1. 使用useRef创建 ref 对象,并与 JSX 绑定
- 2.在DOM可用时,通过 inputRef.current 拿到 DOM 对象
- 三、发表评论案例
- 四、组件通信
- 1.父子通信
- (1)父传子
- (2)props说明
- 特殊的prop children
- (3)子传父
- 2.使用状态提升实现兄弟组件通信
- 3.使用Context机制跨层级组件通信
- 五、useEffect
- 1.基本使用
- 2.依赖项参数说明
- 3.清楚副作用
- 六、自定义hook函数
- 七、ReactHooks使用规则
- 1. 只能在组件中或者其他自定义Hook函数中调用
- 2. 只能在组件的顶层调用,不能嵌套在 if、for、其他函数中
- 八、优化评论案例
- 1.通过接口获取评论列表
- 2.自定义Hook函数封装数据请求
- 3.封装评论项Item组件
一、受控表单绑定
1.准备React状态值
const [value,setValue]
=useState(")
2.通过value属性绑定状态,通过onChange属性绑定状态同步的函数
<input
type="text"
value={value}
onChange={(e)=>setValue(e.target.value)}
/>
二、React中获取DOM
在 React 组件中获取/操作 DOM,需要使用 useRef React Hook钩子函数,分为两步
1. 使用useRef创建 ref 对象,并与 JSX 绑定
2.在DOM可用时,通过 inputRef.current 拿到 DOM 对象
可用:DOM渲染完毕时可用
//app.js
import {useRef} from "React"
function App(){
const inputRef=useRef(null)
const getDom=()=>{
console.log(inputRef.current)
}
return(
<div>
<input type="text" ref={inputRef}/>
<button onClick={getDom}>获取Dom<button/>
<div/>
)
}
三、发表评论案例
需求:获取评论内容 ;点击发布按钮发布评论
1.准备状态值
2.实现双向绑定
3.绑定点击事件并声明回调
优化:rpid要求一个唯一的随机数id - uuid;ctime要求以当前时间为标准,生成固定格式 - dayjs
dayjs官网:https://day.js.org/docs/en/installation/node-js
清空内容并重新聚焦
-
清空内容 - 把控制input框的value状态设置为空串
-
重新聚焦 - 拿到input的dom元素,调用focus方法
四、组件通信
概念:组件通信就是组件之间的数据传递,根据组件嵌套关系的不同,有不同的通信方法
1.父子通信
(1)父传子
父组件传递数据 -在子组件标签上绑定属性
子组件接收数据 - 子组件通过props参数接收数据
//子组件
function Son(props){
console.log(props)
return <div>hi,I am {props.name}'s son </div>
}
//父组件
function App(){
const name="Jack"
return(
<div>
<Son name={name}></Son>
<div/>
)
}
注:props对象里包含了父组件传递过来的所有数据
(2)props说明
props可传递任意的数据:数字、字符串、布尔值、数组、对象、函数、JSX;props是只读对象,子组件只能读取props中的数据,不能直接进行修改, 父组件的数据只能由父组件修改
特殊的prop children
当我们把内容嵌套在子组件标签中时,父组件会自动在名为children的prop属性中接收该内容
(3)子传父
核心思路:在子组件中调用父组件中的函数并传递参数
import {useState} form "react"
function Son({onGetMsg}){
const sonMsg="this is son Msg "
return {
<div>
this is son
<button onClick={()=>onGetSonMsg(sonMsg)}>点我发送给父组件<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/>
)
}
2.使用状态提升实现兄弟组件通信
实现思路:借助“状态提升”机制,通过共同的父组件进行兄弟组件之间的数据传递
A组件先通过子传父的方式把数据传给父组件App
App拿到数据后通过父传子的方式再传递给B组件
3.使用Context机制跨层级组件通信
实现思路:使用createContext方法创建一个上下文对象Ctx
在顶层组件(App)中通过 Ctx.Provider 组件提供数据
在底层组件(B)中通过 useContext 钩子函数获取消费数据
五、useEffect
1.基本使用
useEffect是一个React Hook函数,用于在React组件中创建不是由事件引起而是由渲染本身引起的操作(副作用), 比如发送AJAX请求,更改DOM等等
上面的组件中没有发生任何的用户事件,组件渲染完毕之后就需要和服务器要数据,整个过程属于“只由渲染引起的操作”
2.依赖项参数说明
依赖项例子中只要count变化也会再次执行
3.清楚副作用
在useEffect中编写的由渲染本身引起的对接组件外部的操作,社区也经常把它叫做副作用操作,比如在useEffect中开启了一个定时器,我们想在组件卸载时把这个定时器再清理掉,这个过程就是清理副作用
说明:清除副作用的函数最常见的执行时机是在组件卸载时自动执行
需求:在Son组件渲染时开启一个定制器,卸载时清除这个定时器
六、自定义hook函数
概念:自定义Hook是以 use 打头的函数,通过自定义Hook函数可以用来实现逻辑的封装和复用
案例需求:点击toggle实现div的消失和隐藏
思路:声明一个use开头的函数,在函数体内封装可复用的逻辑,把组件中用到的状态或者回调return出去,在哪个组件中用到这个逻辑就执行这个函数,结构出状态和回调即可使用。
自定义封装useToggle函数:
七、ReactHooks使用规则
1. 只能在组件中或者其他自定义Hook函数中调用
2. 只能在组件的顶层调用,不能嵌套在 if、for、其他函数中
八、优化评论案例
需求: 使用请求接口的方式获取评论列表并渲染 ;使用自定义Hook函数封装数据请求的逻辑;把评论中的每一项抽象成一个独立的组件实现渲染
1.通过接口获取评论列表
(1). 使用 json-server 工具模拟接口服务, 通过 axios 发送接口请求,json-server是一个快速以.json文件作为数据源模拟接口服务的工具,axios是一个广泛使用的前端请求库
安装json-server:
安装:npm i json-server -D
创建一个db.json的文件
在package.json文件的脚本执行命令中添加一条"serve":"json-server db.json --port 3004"
执行npm run serve运行命令
安装axios:
npm install axios
4542d.png)
(2). 使用 useEffect 调用接口获取数据
2.自定义Hook函数封装数据请求
(1)编写一个use开头的函数
(2)函数内部编写封装逻辑
(3)return 出去组件中用到的状态和方法
(4)组件中调用函数解构赋值使用
3.封装评论项Item组件
抽象原则:App作为“智能组件”负责数据的获取,Item作为“UI组件”负责数据的渲染
删除功能变成了需要子传父
父组件:
子组件: