目录
一、表单受控绑定
使用React组件的状态(useState)控制表单的状态

就是你往input里输入内容,然后state用onChange 事件监听到输入框内容变化,于是用setName更改name属性,也就是这个变量值变了,然后数值驱动试图,input框里的内容跟着显示出来。
(虽然输入框显示键盘输入的内容是浏览器的默认行为,但是这个默认行为下js并不知道你写了什么,除非document.xx去获取。但是这种表单受控绑定的情况下react就知道你写了什么并且由他给你展示在页面上)
(展示动作是浏览器完成的,展示什么内容是react决定的)
import { useState } from "react";
function Son() {
const [name,setName]=useState('')
const setName1=(value)=>{
setName(value)
}
const nameChange=(e)=>{
console.log(e.target.value)
setName1(e.target.value)
}
return (
<div>
<input onChange={
nameChange
} value={name}></input>
</div>
);
}
export default Son;
二、React中获取DOM
目前基本都是要数据驱动视图,不建议直接去操作dom,但是某些情况需要我们操作dom,需要使用useRef钩子函数
-
使用useRef创建Ref对象,并与JSX绑定
-
ref.current获取dom值
import { useState } from "react";
import { useRef } from "react";function Son1() {
//获取ref对象,初始值为null,并把这个对象绑定到dom身上去
const inputRef=useRef(null)
//然后这个对象.current获取dom
console.log(inputRef.current)
return (
<input ref={inputRef} value={'11'}>
);
}export default Son1;
不过需要注意第二步在dom渲染完毕的时候才能用
三、组件间通信
1.父传子
依旧是标签给子传,子用props接收
父:
import { useState } from "react";
import Son1 from './components/Son1'
function App() {
return (
<div>
<Son1 name={'hh'} />
</div>
);
}
export default App;
子:(props接收来的数据只读)
import { useState } from "react";
function Son1(props) {
console.log(props,'99')
return (
<div>11</div>
);
}
export default Son1;
props是个对象
可以传递数字、字符串、布尔、数组、对象、函数、JSX
特殊的prop------children
把内容直接嵌套在子组件标签里,然后在子组件的pros.children里去找
<Son1>
<span>111 </span>
</Son1>

2.子传父
依旧是子调用父的方法
父:
import { useState } from "react";
import Son1 from './components/Son1'
const fn_f=(x)=>{
console.log(x,'888')
}
function App() {
return (
<div>
<Son1 fn_f={fn_f}></Son1>
</div>
);
}
export default App;
子:
import { useState } from "react";
import { useRef } from "react";
function Son1(props) {
console.log(props,'99')
props.fn_f('hhh')
return (
<div>
111
</div>
);
}
export default Son1;

注意:useState 必须写在 function 组件名() {} 的函数体内部。
3.兄弟间组件通信
(1)儿子A给父通信,然后父再把拿到的数据传给儿子B
比较简单就不再放代码了
(2)Context机制跨层级组件通信(从上到下)
- 使用createContext方法创建一个上下文对象Ctx
- 在顶层组件用Ctx.provider组件提供数据
- 底层组件通过useContext钩子函数获取数据
顶级组件:
import { useState } from "react";
import Son1 from './components/Son1'
import Son2 from './components/Son2'
import { createContext } from "react";
const msg="Hello React!";
export const Ctx=createContext()
function App() {
return (
<div>
<Son1 fn_f={fn_f}></Son1>
<Ctx.Provider value={msg}>
<Son2></Son2>
</Ctx.Provider>
</div>
);
}
export default App;
底层组件:
import { useContext, useState } from "react";
import { useRef } from "react";
import { Ctx } from "../App";
function Son2(props) {
const btn=()=>{
// console.log(props,'99')
}
const msg = useContext(Ctx);
console.log(msg,'99')
return (
<div>
<input onClick={btn}></input>
</div>
);
}
export default Son2;
我是在两个文件里写的,所以Ctx还需要导出导入一下,不过我感觉特别不好,我都导出了还要你Context干嘛(不过export导出的变量组件不能监听变化以及自动更新,而context可以)
四、useEffect
1.基础
useEffect是一个React的React Hook函数,用于在组件中创建不是由事件引起而是由渲染本身引起的操作,比如发送AJAX请求、更改DOM(就像mounted干的事一样,用户没有任何操作,但是渲染完了就自动去发请求)
userEffect(()=>{},[])
第一个参数是一个箭头函数,也叫副作用函数,放要执行的操作
第二个参数是数组(可选参),在数组里放依赖项,不同的依赖项会影响第一个函数参数的执行,空数组的时候,副作用函数只在渲染完毕之后执行一次。
2.不同依赖项

第一种是这个参数压根不传,组件更新指的是组件函数重新渲染了一次,比如state变化、props变化、父组件重新渲染了
第三种比如下面这种,只有count和name变化之后才会有hh输出
userEffect(()=>{
console.log('hh')
},[conut,name])
3.useEffect清除副作用
就像定时器在vue里要在组件卸载的时机去清理一样,语法:
userEffect(()=>{
//副作用代码(订阅、定时器、事件监听等)
return()=>{
//清除副作用逻辑
}
},[])
所以这个userEffect类似mounted(但又不仅仅是mounted,还有点监听器的作用),里面的return类似unmounted
五、自定义Hook实现
自定义Hook是以use打头的函数,通过自定义Hook函数可以用来实现逻辑的封装和复用,就是用use打头命名的一个function,最后把需要的东西return出去供组件或其他Hook函数使用。
ReactHooks使用规则(这里不只自定义的,还有useState、useEffect、useContext、useRef、useReducer、useCallback、useMemo 等等):
- 只能在组件或其他Hook函数使用
- 只能在组件的顶层调用,不能嵌套在if、for、其他函数中(React靠调用次序来记住Hooks,而不是靠名字,如果放if/for/其他函数里的话就会搞混顺序)