React的Hooks相关API与Redux状态管理

前言:Hook是raect16.8之后新增的特征,它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。Redux是相关数据处理与状态管理

新老生命周期对比

React16.2及之前版本

16.3之前生命周期

React16.3之后版本

React16.3之后版本

先看一下class组件的代码

import React from 'react';
import moment from 'moment';
import styles from './index.less';

class ComboInfo extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      iciTag: false,
      coverVideoVisible: false,
    };
    this.isCheckIciTag = false;
  }

  componentDidMount() {
    const { comboInfo = {} } = this.props;
    if (comboInfo.id && !this.isCheckIciTag) {
      this.checkIciTag();
    }
  }

  componentDidUpdate() {
    const { comboInfo = {} } = this.props;
    if (comboInfo.id && !this.isCheckIciTag) {
      this.checkIciTag();
    }
  }

  render() {
    const { onPay, comboInfo, onReceiveCoupon, coupon } = this.props;
    const { courseList = [] } = comboInfo;
    const { iciTag, coverVideoVisible } = this.state;
    return (
      <div className={styles.boxMain}>
        //其他的DOM结构
      </div>
    );
  }
}

export default ComboInfo;
具有特殊意义------类组件的缺点
①props①逻辑分散
②state②数据分散
③setState③组件拆分繁琐
④render④state树往往较大
⑤生命周期钩子函数⑤组件与生命钩子高度耦合

Hooks的API

基础Hooks

useState:

该函数将接收先前的 state,并返回一个更新后的值

import React, { useState, useEffect } from 'react';
function Counter() {
  const [count, setCount] = useState(0);
  function handleClick() {
    setCount(count + 1)
  }
  return (
    <>
      Count: {count}
      <button onClick={handleClick}>+</button>
    </>
  );
}

useEffect

使用useEffect是模拟class组件componentDidMount、componentWillUnmount、componentDidUpdate。当每次的状态state/props的某些值发生变化而进行监听

import React, { useState, useEffect } from 'react';
function Welcome(props) {
  useEffect(() => {
    document.title = `Hello, ${props.name}`;
  }, [props.name]);
  return <h1>Hello, {props.name}</h1>;
}

注意事项
①执行useEffect可能会有副作用( 数据获取,数据订阅,以及手动更改 React 组件中的 DOM 都属于副作用)。并且例如订阅外部数据源,添加DOM事件。这种情况下,清除工作是非常重要的,可以防止引起内存泄露
②useEffect的参数说明:

参数参数类型参数说明
第一个参数函数FunctuousReact 组件需要在渲染后执行哪些操作,这个函数会在DOM更新之后被调用。利用第二个参数可控
第二个参数数组Array依赖state/props的某个值变化而执行,如诺未传参则默认被调用

useContext

import React, { useState, useEffect,useContext } from 'react';
const value = useContext(MyContext);

const {Provider, Consumer} = React.createContext(defaultValue);//creatContext结构说明

接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定。(更好的理解:useContext是为了接受较外层的某个值的容器,不需要一层层通过props传递)。

//这是外层需要传递的祖先组件
import React from 'react';
import Page_1 from './pages/Page_1'; //需要传递的后代组件

const deafultContxt = { name: 'youwne'};

export const appContext = React.createContext(deafultContxt);
function App() {
  return (
    <appContext.Provider value={deafultContxt}>
      <Page_1 />
    </appContext.Provider>
  );
}
export default App;
//需要取祖先组件某个值的后代组件
import React, { useContext } from 'react';
import { appContext } from '../App';	// 引入需要取值的祖先组件

//方式一:
export default function Page1() {
  return (
    <appContext.Consumer>
      {/* 通过 value 来输出你的自定义属性 */}
      {({ name }) => <h3>{name}</h3>}
    </appContext.Consumer>
  );
}

//方式二:
export default function Page1() {
  const { name } = useContext(appContext);
  return <h3>{name}</h3>;
}

额外的 Hooks

useReducer

const [state, dispatch] = useReducer(reducer, initialArg, init);

useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法。

function init(initialCount) {
  return {count: initialCount};
}

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    case 'reset':
      return init(action.payload);
    default:
      throw new Error();
  }
}

function Counter({initialCount}) {
  const [state, dispatch] = useReducer(reducer, initialCount, init); //init为惰性初始化,可不传
  return (
    <>
      Count: {state.count}
      <button
        onClick={() => dispatch({type: 'reset', payload: initialCount})}>
        Reset
      </button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

useCallback

把内联回调函数及依赖项数组作为参数传入 useCallback,它将返回该回调函数的 memoized 版本,该回调函数仅在某个依赖项改变时才会更新

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

useMemo

把“创建”函数和依赖项数组作为参数传入 useMemo,它仅会在某个依赖项改变时才重新计算 memoized 值。这种优化有助于避免在每次渲染时都进行高开销的计算。返回一个 memoized 值

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

useRef

const refContainer = useRef(initialValue);

useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` 指向已挂载到 DOM 上的文本输入元素
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>输入框获取光标</button>
    </>
  );
}

:其他的hooks相关API暂不描述

Redux状态管理

Redux处理流程图例

Redux处理流程图例

Redux优点

①单一数据流Stores②状态是只读的③状态的改变只能通过纯函数Reducer操作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咕咕鱼123_blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值