前言
在 React Hooks
中,分为基础 Hook
和额外的 Hook
,这之前的文章中有写到过基础的 Hook
中的 useState和useEffect的运用,那么今天就跳过这两个 Hook
继续向下介绍部分 Hook
~
useMemo
useMemo
是可以作为性能优化,把创建函数和依赖项作为参数,它仅仅在依赖项改变时才会重新计算。
import React, { useState, useMemo } from 'react';
const Child = ({ name, age }) => {
// 将创建函数和依赖项作为参数,当依赖项发生改变时才会重新计算
useMemo(() =>{
console.log( "更新" );
}, [ name, age ]);
return (
<>
<p>children {name}:{age}</p>
</>
)
}
const UseMemo = () => {
const [name, setname] = useState('张三');
const [age, setage] = useState(18);
return (
<>
<button onClick={() => setname('李四')}>修改名字</button>
<button onClick={() => setage(22) }>修改年龄</button>
<p>UseMemo {name}:{age}</p>
<Child age={age} name={name} />
</>
)
};
export default UseMemo;
useRef
useRef
可以使你方便的访问子组件,可以保存任何的值。
const UseRef = () => {
const refvalue = useRef(null);
function addRef(){
refvalue.current.value = '张三'; // 点击按钮时候给这个ref赋值
// refvalue.value = '张三'; // 这样写没有绑定在dom上,其值依然在ref上
refvalue.current.focus();
}
return (
<>
<button onClick={ addRef }>插入名称</button>
<input ref={refvalue} />
</>
)
}
export default UseRef;
useContext
通过 React.createContext
创建出来的上下文,子组件可以通过 useContext
获取内容。
import React, { useState, useContext } from 'react';
// 创建
const MyContext = React.createContext(null);
const Child = ({ count }) => {
// 子组件通过 useContext 获取
const { setCount } = useContext(MyContext);
return (
<>
<p>{ count }</p>
<button onClick={() => setCount( count + 1 )}>点击</button>
</>
)
}
const UseContext = () => {
const [count, setCount] = useState(0);
return (
<>
<MyContext.Provider value={{ setCount }}>
<Child count={ count } />
</MyContext.Provider>
</>
)
}
export default UseContext;
当然使用这个有一个尴尬的情况,就是子组件和父组件不在同一个路径下的情况下,我们不能够去共享这个 Context
实例,这个时候我们需要创建一个上下文管理的组件,来统一导出 Context
实例。
// src/context-manmger.js
import React from 'react';
export const MyContext = React.createContext(null);
接着我们就可以在这个子组件和父组件中导入这个上下文管理组件实现共享。
// src/compontents/Child.js
import React, { useContext } from 'react';
import { MyContext } from '../context-manager';
const Child = ( props = {}) => {
const { setCount } = useContext(MyContext);
return (
<div>
<p>{ props.count }</p>
<button onClick={ () => setCount( props.count + 1 ) }>点击</button>
</div>
)
}
export default Child;
import React, { useState } from 'react';
import { MyContext } from './context-manager';
import Child from './components/Child';
const UseContext = () => {
const [count, setCount] = useState(0);
return (
<>
<MyContext.Provider value={{ setCount }}>
<Child count={count} />
</MyContext.Provider>
</>
)
}
export default UseContext;
useReducer
useReducer
是 useState
的代替方案,搭配其配套的 dispatch
方法将更加的灵活。
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [ state, dispatch ] = useReducer(reducer, { count: 0 });
return (
<>
Count:{ state.count }
<button onClick={ () => dispatch( { type: 'decrement' } ) }> - </button>
<button onClick={ () => dispatch( { type: 'increment' } ) }> + </button>
</>
)
}
export default Counter;