hooks
1.hooks 是利用 userReducer 和 context 实现通讯,下面模拟实现一个简单的 redux
2.核心文件分为 action,reducer,types
action.js
import * as Types from './types';
export const onChangeCount = count => ({
type: Types.EXAMPLE_TEST,
count: count + 1
})
复制代码
reducer.js
import * as Types from "./types";
export const defaultState = {
count: 0
};
export default (state, action) => {
switch (action.type) {
case Types.EXAMPLE_TEST:
return {
...state,
count: action.count
};
default: {
return state;
}
}
};
复制代码
types.js
export const EXAMPLE_TEST = 'EXAMPLE_TEST';
复制代码
eightteen.jsx
export const ExampleContext = React.createContext(null);//创建createContext上下文
// 定义组件
function ReducerCom() {
const [exampleState, exampleDispatch] = useReducer(example, defaultState);
return (
<ExampleContext.Provider
value={{ exampleState, dispatch: exampleDispatch }}
>
<EightteenChildThree></EightteenChildThree>
</ExampleContext.Provider>
);
}
复制代码
EightteenChildThree.jsx // 组件
import React, { useEffect, useContext } from 'react';
import {Button} from 'antd'
import {onChangeCount} from '../../pages/TwoTen/store/action';
import { ExampleContext } from '../../pages/TwoTen/eighteen';
const Example = () => {
const exampleContext = useContext(ExampleContext);
useEffect(() => { // 监听变化
console.log('变化执行啦')
}, [exampleContext.exampleState.count]);
return (
<div>
<p>值为{exampleContext.exampleState.count}</p>
<Button onClick={() => exampleContext.dispatch(onChangeCount(exampleContext.exampleState.count))}>点击加 1</Button>
</div>
)
}
export default Example;
复制代码
3.hooks其实就是对原有React 的 API 进行了封装,暴露比较方便使用的钩子;
4.钩子有:
| 钩子名 | 作用 |
|---|---|
| useState | 初始化和设置状态 |
| useEffect | componentDidMount,componentDidUpdate和componentWillUnmount和结合体,所以可以监听useState定义值的变化 |
| useContext | 定义一个全局的对象,类似 context |
| useReducer | 可以增强函数提供类似 Redux 的功能 |
| useCallback | 记忆作用,共有两个参数,第一个参数为一个匿名函数,就是我们想要创建的函数体。第二参数为一个数组,里面的每一项是用来判断是否需要重新创建函数体的变量,如果传入的变量值保持不变,返回记忆结果。如果任何一项改变,则返回新的结果 |
| useMemo | 作用和传入参数与 useCallback 一致,useCallback返回函数,useDemo 返回值 |
| useRef | 获取 ref 属性对应的 dom |
| useImperativeMethods | 自定义使用ref时公开给父组件的实例值 |
| useMutationEffect | 作用与useEffect相同,但在更新兄弟组件之前,它在React执行其DOM改变的同一阶段同步触发 |
| useLayoutEffect | 作用与useEffect相同,但在所有DOM改变后同步触发 |
5.useImperativeMethods
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeMethods(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);
复制代码
slot
slot 就是将父组件的标签传给子组件,类似vue 的 v-slot
场景:有些组件只是共用部分dom 逻辑,里面有部分逻辑是独立的
// 父组件文件
import SlotChild from 'SlotChild'
<SlotChild
slot={<div>这是父组件的 slot</div>}>
</SlotChild>
// 子组件
子组件直接获取 this.props.slot 就可获取到内容
复制代码
对比
| 方法 | 优点 | 缺点 |
|---|---|---|
| props | 不需要引入外部插件 | 兄弟组件通讯需要建立共同父级组件,麻烦 |
| props 升级版 | 不需要引入外部插件,子传父,不需要在父组件用方法接收 | 同 props |
| Provider,Consumer和Context | 不需要引入外部插件,跨多级组件或者兄弟组件通讯利器 | 状态数据状态追踪麻烦 |
| EventEmitter | 可支持兄弟,父子组件通讯 | 要引入外部插件 |
| 路由传参 | 可支持兄弟组件传值,页面简单数据传递非常方便 | 父子组件通讯无能为力 |
| onRef | 可以在获取整个子组件实例,使用简单 | 兄弟组件通讯麻烦,官方不建议使用 |
| ref | 同 onRef | 同 onRef |
| redux | 建立了全局的状态管理器,兄弟父子通讯都可解决 | 引入了外部插件 |
| mobx | 建立了全局的状态管理器,兄弟父子通讯都可解决 | 引入了外部插件 |
| flux | 建立了全局的状态管理器,兄弟父子通讯都可解决 | 引入了外部插件 |
| hooks | 16.x 新的属性,可支持兄弟,父子组件通讯 | 需要结合 context 一起使用 |
| slot | 支持父向子传标签 |
redux , mobx和flux对比
| 方法 | 介绍 |
|---|---|
| redux | 1.核心模块:Action,Reducer,Store;2. Store 和更改逻辑是分开的;3. 只有一个 Store;4. 带有分层 reducer 的单一 Store;5. 没有调度器的概念;6. 容器组件是有联系的;7. 状态是不可改变的;8.更多的是遵循函数式编程思想 |
| mobx | 1.核心模块:Action,Reducer,Derivation;2.有多个 store;3.设计更多偏向于面向对象编程和响应式编程,通常将状态包装成可观察对象,一旦状态对象变更,就能自动获得更新 |
| flux | 1.核心模块:Store,ReduceStore,Container;2.有多个 store; |
| 本文章为自己学习的总结文章,文章参考于火狼1 |