react hooks的应用
useContext(context)
import React, { useContext } from 'react'
const bgcolor = {
bgf: {background: "red"},
bgs: {background: "blue"}
}
const themeContext = React.createContext(bgcolor.bgf);//创建以bgcolor.bgf为默认值context上下文
export default function ReactHook() {
return (
<div>
<themeContext.Provider value={bgcolor.bgs}>//提供值bgcolor.gbs给包含的组件以及后代组件
<Test />
</themeContext.Provider>
</div>
)
}
function Test() {
return (
<div>
直接使用useContext返回值(第一种):<ThemedButton />
<br />
<hr />
<br />
直接使用themeContext.Consumer返回值(第二种):<ThemedButtonConsumer />
<br />
<hr />
<br />
直接使用ReactHook.contextType(static)返回值(第三种):<ThemedButtonStatic />
<br />
<hr />
<br />
直接使用ReactHook.contextType(class)返回值(第四种):<ThemedButtonClass />
</div>
)
}
//第四种
class ThemedButtonClass extends React.Component {
componentDidMount() {
console.log(this.context)
}
render() {
return (
<div style={{ background: this.context.background }}>
ReactHook.contextType
</div>
)
}
}
ThemedButtonClass.contextType = themeContext;
//第三种
class ThemedButtonStatic extends React.Component {
static contextType = themeContext;
componentDidMount() {
console.log(this.context)
}
render() {
return (
<div style={{ background: this.context.background }}>
ReactHook.contextType
</div>
)
}
}
//第二种
function ThemedButtonConsumer() {
return (
<div>
<themeContext.Consumer>
{value => {
console.log(value)
return (
<div style={{ background: value.background }}>
consumer
</div>
)
}}
</themeContext.Consumer>
</div>
)
}
//第一种
function ThemedButton() {
const contextV = useContext(themeContext)
console.log(contextV);
return (<div style={{ background: contextV.background }}>usecontext</div>)
}
结果:如下图所示
useReducer
import React,{useReducer} from 'react'
const initstate={count:0}
const reducer=(state,action)=>{
switch(action.type){
case 'add':
return {count:state.count+1}
case 'reduce':
return {count:state.count - 1}
default:
return state.count
}
}
export default function UseReducerTest() {
const [state, dispatch] = useReducer(reducer, initstate);
console.log(state,dispatch);
return (
<div>
<button onClick={()=>{dispatch({type:'add'})}}>+</button>
{state.count}
<button onClick={()=>{dispatch({type:'reduce'})}}>-</button>
</div>
)
}
useMemo(调用函数并返回其结果)
原因:
- class组件调用setState,无论state的值是否改变都会触发组件重新渲染,可以通过shouldComponentUpdate比较前后state的值是否发生变化,通过return false阻止更新。
- 在函数组件中,react不再区分挂载跟更新两个状态,这意味着函数组件的每一次调用都会执行其内部的所有逻辑,那么会带来较大的性能损耗。所以通过useMemo跟useCallback解决这个问题。
//没有添加useMemo之前,改变name,ChangeAge函数会被触发
import React, { useState, useMemo } from 'react'
export default function UseMemoDemo() {
const [age, setAge] = useState(18);
const [name, setName] = useState('lili');
const ChangeAge = () => {
console.log('change age1');
return <div>age1:{age}</div>
}
return (
<div>
<button onClick={() => {
setAge(age + 1)
}}>改变age</button>
<button onClick={() => {
setName('dd')
}}>改变name</button>
<ChangeAge1 />
{name}:{age}
</div>
)
}
//添加了useMemo,之后
import React, { useState, useMemo } from 'react'
export default function UseMemoDemo() {
const [age, setAge] = useState(18);
const [name, setName] = useState('lili');
const ChangeAge = useMemo(() => {//函数在初始化的时候会执行,其后,只有当依赖项age改变的时候,ChangeAge函数才会执行
console.log('age change')
return <div>age:change{age}</div>
}, [age])
const ChangeName = useMemo(() => {//函数在初始化的时候会执行,其后,当依赖项name改变的时候,ChangeName函数才会执行
console.log('name change');
return <div>name:{name}</div>
}, [name])
return (
<div>
<button onClick={() => { //改变age的值
setAge(age + 1)
}}>改变age</button>
{name}:{age}
<button onClick={() => { //改变name的值,多次点击这个函数,但ChangeName也最多只能执行一次,因为name在点击一次之后值修改为tom,其后点击name的值不变。
setName('tom')
}}>改变name</button>
<input type="text" value={name} //输入值,可以改变name的值,每次输入都能触发ChangeName函数
placeholder="改变name"
onChange={e=>{setName(e.target.value)
}}/>
</div>
)
}
useCallback ( 返回函数而不调用)
import React,{useState,useCallback} from 'react'
export default function UseCallbackdemo() {
const [age, setAge] = useState(18)
const [name, setName] = useState('lili');
const c = useCallback( //当age的值发生改变时,才会返回新的函数
() => {
console.log('调用了函数c');
},
[age],
)
return (
<div>
<Header c={c} />
<button onClick={() => { setAge(age + 1) }}>changeAge</button>
<button onClick={() => { setName('dd') }}>changeName</button>
{name}:{age}
</div>
)
}
function Header(props){
const {c}=props;
console.log('render')
return <p onClick={c} style={{color:'red'}}>change</p>
}
Header=React.memo(Header); //React.memo 仅检查 props 变更,当 state 或 context 发生变化时,它仍会重新渲染。
函数组件的useRef跟类组件的React.createRef()
useRef
import React, { useRef } from 'react'
export default function UseRefdemo() {
const ref = useRef('');
return (
<div>
<input type="text" ref={ref} />
<button onClick={() => {
ref.current.focus()
console.log(ref.current.value);
}}>点击</button>
</div>
)
}
React.createRef()
import React, { Component } from 'react'
export default class UseRefdemo extends Component {
constructor(props){
super(props);
this.inputref=React.createRef();
}
render() {
return (
<div>
<input type="text" ref={this.inputref}/>
<button onClick={()=>{
this.inputref.current.focus()
console.log(this.inputref.current.value)
}}>获取焦点</button>
</div>
)
}
}
参考链接
https://blog.csdn.net/qq_39081974/article/details/114380881?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-1.no_search_link&spm=1001.2101.3001.4242.2