import React,{ useEffect,useState } from 'react';
- 告别了令人疑惑的生命周期
- 告别类组件中烦人的this
- 告别繁重的类组件,回归到了熟悉的函数组件
useState
1.基础使用
import { useState } from 'react' function App() { // 参数:状态初始值比如,传入 0 表示该状态的初始值为 0 返回值:数组,包含两个值:1 状态值(state) 2 修改该状态的函数(setState) const [count,setCount] = useState(0); 修改count内容 const modifyEvent = () => { setCount(count + 1) } return ( <button onClick={() => modifyEvent()}>{count}</button> ) } export default App
2.状态的读取和修改执行流程与逻辑
1.setCount是一个函数,参数表示最新的状态值
2.调用该函数后,将使用新值替换旧值
3.修改状态后,由于状态发生变化,会引起试图变化 注意
事项:修改状态的时候,一定要使用新的状态替换旧的状态,不能直接修改旧的状态,尤其是引用类型
3. 组件的更新过程
1.组件第一次渲染
- 从头开始执行该组件中的代码逻辑
- 调用 useState(0) 将传入的参数作为状态初始值,即:0
- 渲染组件,此时,获取到的状态 count 值为: 0
2.组件第二次渲染
- 点击按钮,调用 setCount(count + 1) 修改状态,因为状态发生改变,所以,该组件会重新渲染
- 组件重新渲染时,会再次执行该组件中的代码逻辑
- 再次调用 useState(0) ,此时 React 内部会拿到最新的状态值而非初始值,比如,该案例中最新的状态值为 1
- 再次渲染组件,此时,获取到的状态 count 值为:1
import { useState } from 'react' App() { const [count,setCount] = useState(0) 在这里可以进行打印 console.log(count,'渲染了') ( <button onClick={() => { setCount(count + 1) }}>{count}</button> ) } export default App
4.使用规则
List(){ 以字符串为初始值 const [name,setName] = useState('cp' 以数组为初始值 const [list,setList] = useState([]) }
2.useState 注意事项
- 只能出现在函数组件或者其他hook函数中
- 能嵌套在if/for/其它函数中(react按照hooks的调用顺序识别每一个hook)
useEffect
1.理解函数副作用
- 数据请求 ajax发送
- 手动修改dom
- localstorage操作
2. 基础使用
下面案例说明,函数组件储存了当前state所有状态,函数初次就会触发他们两个的加载,另外当某一个发生改变了 useEffect和函数都会被重新执行加载
import { useEffect,useState } from 'react' ) useEffect(()=>{ 修改了dom数据后 userffect函数被副作用重新执行 console.log('执行了副作用函数') }); 函数组件也会被重新执行 console.log('函数组件被重新执行了' ) } export default App
3.useEffect依赖项和控制执行的时机
import { useEffect,useState } from 'react' ) useEffect(()=> 修改了dom数据后 userffect函数不会在被触发,只有首次加载函数才会执行一次 console.log('执行了副作用函数') },[]); 修改了dom数据后 函数组件会被重新执行 console.log('函数组件被重新执行了'default App
添加特定项作为依赖
副作用函数在首次渲染时执行,在依赖项发生变化时重新执行
给useEffect添加特定的依赖项,当这个依赖性的state发生改变,useEffect与函数组件都会重新渲染被执行,由于第二个参数是依赖项所以是数组可以添加多个依赖项
没有useEffect添加的特定的依赖项,就不会触发useEffect函数,只会触发组件的渲染函数
App() { const [count,1)">) const [name,setName] = useState('zs') useEffect(() => { console.log('副作用执行了') },[count]) console.log('组件被执行了') ( <> <button onClick={() => { setCount(count + 1) }}>{count}</button> <button onClick={() => { setName('cp') }}>{name}</button> </> ) }
清理副作用
App() { const [count,1)">) const [name,1)">) useEffect(() => { console.log('副作用执行了') return () => { alert(1) console.log('执行了清楚副作用,组件卸载的时候执行') } },[count]) console.log('组件被执行了' ( <> <button onClick={() => { setCount(count + 1) }}>{count}</button> <button onClick={() => { setName('cp') }}>{name}</button> </> ) }
useMemo(性能优化)
解决函数组件的性能问题,比如子组件重复执行问题,每次渲染都进行高开销的计算
子组件 Sub(props) { console.log("Sub render"); let { number,onClick } = props ( <button onClick={onClick}>{number}</button> ) } 父组件 Test() { let [value,setvalue] = useState('') let [number,setNumber] = useState(0) const addClick = () => setNumber(number + 1return <> <input type="text" value={value} onChange={(e) => setvalue(e.target.value)} /> <Sub number={number} onClick={addClick} /> </> } export default Test;
子组件依赖的只有number ,理想情况下只希望number变化时触发子组件重新渲染
但实际是在输入框内的值发生变化,子组件也会重新渲染 如果子组件的逻辑较复杂,就是无意义的大量计算,浪费资源
使用useMemo记住计算后的值,只有当依赖number变量发生变化,才会重新计算子组件内容 const MemoSub = useMemo( () => <Sub data={number} onClick={addClick} />,[number] 只有 number 变化才重新计算 MenoSub ) return <> <input type="text" value={value} onChange={(e) => setvalue(e.target.value)} /> {MemoSub} </> default Test;
useCallback(性能优化)
接收两个参数:回调函数和依赖项数组。回调函数是需要缓存的函数,依赖项数组用于确定何时需要重新创建函数实例。
当依赖项数组中的任何一个值发生变化时,useCallback 将返回一个新的函数实例,否则它将返回之前缓存的函数实例
import { useState,useCallback } from 'react'; MyComponent() { const [count,1)">); 使用 useCallback 缓存 handleclick 函数 const handleclick = useCallback(() => { setCount(count + 1); },[count]); ( <div> <p>You clicked {count} times</p> {/* 在按钮上使用缓存的 handleclick 函数 */} <button onClick={handleclick}>Click me</button> </div> ); }
在这个例子中,我们使用 useCallback 来缓存回调函数 handleclick, 将其缓存以避免在每次重新渲染组件时创建新的函数实例。
同时,在按钮上使用了缓存的 handleclick 函数,以确保点击按钮时调用的是缓存的函数实例。我们还将 count 添加到依赖项数组中,以确保每当 count 发生变化时,handleclick 都会被重新创建。
useCallback 和 useMomeo 的区别
1.useCallback 和 useMemo 都是用于性能优化的 React 钩子函数,它们都可以避免不必要的重新计算或重新渲染。虽然它们看起来很相似,但它们有几个重要的区别。
2.首先,useCallback 返回一个缓存的回调函数,而 useMemo 返回一个缓存的值。这意味着 useCallback 的主要作用是为一个函数创建缓存,而 useMemo 的主要作用是缓存一个值
3.最后,它们的使用场景也不同。useCallback 适用于优化回调函数,避免不必要的重新渲染,并传递给子组件。而 useMemo 适用于优化计算开销较大的值,如大型数组或对象的计算
useRef
useRef 可以缓存所有数据类型,更新的数据不会随着组件的重新渲染而重置,会一直保持最新状态的内容,
但是保存的数据类型 无法在ui渲染页面上使用,只能作为一个状态进行储存
也可以绑定给一个元素标签获取dom进行操作
Test() { 保存 DOM const inputEl = useRef() const onClick = () => { console.log(inputEl); 对象类型,只有一个 current 属性指向指定DOM inputEl.current.innerHTML = '2asdasd sd阿萨德' } return <div> <div ref={inputEl}></div> <button onClick={onClick}>click me!!!</button> <br /> </div> }
useContext
usecontext React 16.3本中新引入的一个特性,它可以让组件之间共享数据十分方便。它属于 React Context API(上下文API),可以让组件层级之间自由传递数据,而使用Context API可以极大地提高组件之间的可复用性。
使用 useContext以使组件树中的任何组件访问到 cntext值,无论它是何种层级的,而且更方便的是,不需要利用props行传递,而只需要一行代码即可
下面案例是同一组件下多个 子组件的上下文通讯
import React,{ createContext,useContext } from 'react'; const ThemeContext = createContext('light') Test() { ( <ThemeContext.Provider value="dark"> <Toolbar theme="dark" /> </ThemeContext.Provider> ) } Toolbar(props) { ( 中间的组件再也不必指明往下传递 theme 了。 <div> <Button /> </div> 子组件中的子组件 Button() { 指定 contextType 读取当前的 themecontext。 React 会往上找到最近的 theme Provider,然后使用它的值。 在这个例子中,当前的 theme 值为 “dark”。 const theme = useContext(ThemeContext) return <button>{ theme }</button> }
垮文件使用usecontext 进行通讯
父组件
import React,{ useState,createContext } from 'react' import Counter from './Counter' export const countContext = createContext() export default Example4() { const [count,1)"> ( <div> <p>你点击了{count}次</p> <button onClick={()=>{setCount(count+1)}}>点击</button> <countContext.Provider value={count}> <Counter /> </countContext.Provider> </div> ) }
子组件
import React,{ useContext } from 'react' import { countContext } from './Example4' Counter() { let count = useContext(countContext) ( <div> <h2>{count}</h2> </div> ) } export default Counter
这样在多级组件使用就减少使用redux,useContext确实好用,起码跨级传递数据不用那么麻烦了
完结,有不足欢迎补充。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件举报,一经查实,本站将立刻删除。