一、useState回调函数
参数只会在组件的初始渲染中起作用,后续渲染时会被忽略。如果初始 state 需要通过计算才能获得,则可以传入一个函数,在函数中计算并返回初始的 state,此函数只在初始渲染时被调用
示例:
import { useState } from "react"
function getDefaultValue () {
for(let i = 0; i < 1000; i++){
}
return '10'
}
function Counter (props) {
const [count, setCount] = useState(() => {
// 这里目的是为了体现初始值经过一定的计算
// 这个计算比较广义的概念
// 只要无法直接确定 需要通过一定的操作之后才可以获取 既可以理解为计算
// 循环遍历一万条数据才能确定初始值是什么
// return props.count
return getDefaultValue()
})
return (
<div>
<button onClick={() => setCount(count + 1)}>{count}</button>
</div>
)
}
function App() {
return (
<div className="App" style={{width: '30%',border: '2px solid #111',padding: '5px'}}>
<Counter count={10}/>
<Counter count={20}/>
</div>
);
}
export default App;
注意:
1.回调函数return出去的值将作为 count
的初始值
2.回调函数中的逻辑只会在组件初始化时执行一次
二、清除副作用--useEffect
清理副作用:可以在副作用函数中的末尾return一个新的函数,在新的函数中编写清理副作用的逻辑
示例:
import { useEffect, useState } from "react"
function Test () {
useEffect(() => {
let timer = setInterval(() => {
console.log('副作用定时器')
},1000)
// 执行时机:在组件销毁时执行
return () =>{
// 清理定时器
clearInterval(timer)
}
},[])
return (
<div>
子组件
</div>
)
}
function App() {
const [show, setShow] = useState(false)
return (
<div className="App" style={{width: '30%',border: '2px solid #111',padding: '5px'}}>
{show ? <Test /> : null}
<button onClick={() => setShow(!show)}>点击</button>
</div>
);
}
export default App;
三、useEffect如何发生网络请求
uerEffect
1.不加依赖项 初始化 和 重新渲染时
2.加[] 初始化执行一次
3.加特定的依赖项 [count,name] 首次执行 和 任意一个变化时执行
示例:
import { useEffect, useState } from "react"
function App() {
const [show, setShow] = useState(false)
useEffect(() => {
async function getData() {
// const result = await fetch('http://geek.itheima.net/v1_0/channels')
// console.log(result)
fetch("http://geek.itheima.net/v1_0/channels")
.then((response) => response.json())
.then((data) => console.log(data));
}
getData()
},[])
return (
<div className="App" style={{width: '30%',border: '2px solid #111',padding: '5px'}}>
<button onClick={() => setShow(!show)}>点击</button>
</div>
);
}
export default App;
注意事项:
fetch:是 浏览器原生支持的一种获取数据的方法
可前往https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch查阅
四、useRef--获取真实dom或组件实例的方法
1. 导入 useRef 函数
2. 执行 useRef 函数并传入null,返回值为一个对象 内部有一个current属性存放拿到的dom对象(组件实例)
3. 通过ref 绑定 要获取的元素或者组件
示例:
import React,{ useEffect, useRef } from "react"
class Test extends React.Component{
state = {
name: 'test'
}
getNumber = () => {
return '这是类组件'
}
render() {
return (
<div>类子组件</div>
)
}
}
function App() {
const testRef = useRef(null)
const h1Ref = useRef(null)
// useEffect函数 在dom渲染之后开始执行
useEffect(() => {
console.log(testRef.current)
console.log(h1Ref.current)
},[])
return (
<div className="App" style={{width: '30%',border: '2px solid #111',padding: '5px'}}>
<Test ref={testRef} />
<h1 ref={h1Ref}>标题1</h1>
</div>
);
}
export default App;
五、useContext
跨组件 Context机制
1. 使用createContext 创建Context对象
2. 在顶层组件通过Provider 提供数据
3. 在底层组件通过useContext函数获取数据
示例:
import React,{ createContext, useContext, useState } from "react"
// 引入封装的Context
import Context from "./context"
// const Context = createContext()
function TestA (){
const count = useContext(Context)
return (
<div>子组件A---
app传过来的数据: {count}
<TestC />
</div>
)
}
function TestC (){
const count = useContext(Context)
return (
<div>
子组件C---
app传过来的数据: {count}
</div>
)
}
function App() {
const [count, setCount] = useState(0)
return (
<Context.Provider value={count}>
<div className="App" style={{width: '30%',border: '2px solid #111',padding: '5px'}}>
<TestA />
<button onClick={() => setCount(count+1)}>+</button>
</div>
</Context.Provider>
);
}
export default App;
context.js
// 1.调用createContext方法
// 2.通过顶层组件包裹一下 Context.Provider
// 3.底层组件 useContext(createContext返回的对象)
import { createContext } from "react";
const Context = createContext()
export default Context
注意事项:
1.Context如果要传递数据 只需要在整个应用初始化的时候传递一次就可以 就选择在index.js文件里做数据提供
2.如果Context需要传递数据并且将来还需要再对数据做修改 底层组件也需要跟着一起改变 就写
到app.js