react自学总结文章2

50 阅读4分钟

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初始化和设置状态
useEffectcomponentDidMount,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建立了全局的状态管理器,兄弟父子通讯都可解决引入了外部插件
hooks16.x 新的属性,可支持兄弟,父子组件通讯需要结合 context 一起使用
slot支持父向子传标签

redux , mobx和flux对比

方法介绍
redux1.核心模块:Action,Reducer,Store;2. Store 和更改逻辑是分开的;3. 只有一个 Store;4. 带有分层 reducer 的单一 Store;5. 没有调度器的概念;6. 容器组件是有联系的;7. 状态是不可改变的;8.更多的是遵循函数式编程思想
mobx1.核心模块:Action,Reducer,Derivation;2.有多个 store;3.设计更多偏向于面向对象编程和响应式编程,通常将状态包装成可观察对象,一旦状态对象变更,就能自动获得更新
flux1.核心模块:Store,ReduceStore,Container;2.有多个 store;
本文章为自己学习的总结文章,文章参考于火狼1