2019-11-27 | UNLOCK | 更新时间:2019-11-27 16:37

Hooks是否取代Redux

  今天,看到新闻高以翔猝死,诶,默哀三秒······。真是世事难料,我们还是应该注意身体,尤其是开发人员,猝死的新闻更是是应接不暇。

先问是不是,在问为什么

  Hook作为React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性.自发布以来,大家就开始利用它来达成各种业务需求。然后,大家就会发出疑问,Hook是否将取代Redux的位置,用于React状态管理?首先知乎热评:先问是不是,在问为什么?那么Hook取代Redux这个问题存不存在呢,我觉得是不存在的。Redux是 JavaScript 状态容器,提供可预测化的状态管理。
而Hook仅仅只是作为React的新特性。Redux的地位自然是无可撼动。

  那Hook是不是能取代Redux在React中的地位呢。我觉得可能会拉走一部分开发人员,毕竟React-redux作为第三方插件,导入项目中,哪怕是打包压缩也会增加项目的大小。当然这是我个人观点,还是得根据实际来看,如果项目状态树复杂多变,项目大而繁琐,那么肯定是需要react-redux来进行状态管理的,那如果项目小状态简单,但是又有扩展需求,那么Hook也是完全可以的。官方表示Hook的开发是针对 “难以复用类组件之前的逻辑,生命周期包含不相关的逻辑,类组件之间的逻辑复杂难理解”这几个问题进行的。文档表示不要滥用context,它会使组件变的难以复用。因此官方可能并未考虑用Hook取代react-redux。所以说了这么多,我的观点是Hook不会取代react-redux的地位。

useContext实现状态共享

  useContext可以让你在组件之间共享应用的状态,而不需要通过prop传递。首先,我们需要了解 context。context提供一种方法,用于全局传递,使得组件之间不用显式地通过 props 传递数据

  • React.createContext: 创建一个 Context 对象,该对象拥有 Provider 和 Consumer 属性
  • Context.Provider: 接受一个 value 参数,在 value 参数更新的时候通知 Consumer
  • Context.Consumer: 订阅 value 参数的改变。一旦 value 参数改变,就会触发它的回调函数
// 第一步:全局创建一个 context
import React,{useContext} from "react";
const UserContext = React.createContext();
...
// 第二步:使用 Provider 提供 ThemeContext 的值,Provider所包含的子树都可以直接访问ThemeContext的值
<ThemeContext.Provider value="dark">
    <Toolbar />
</ThemeContext.Provider>
...
// Toolbar 组件并不需要透传 ThemeContext
function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}
function ThemedButton(props) {
  // 第三步:使用共享 Context
  const theme = useContext(ThemeContext);
  render() {
    return <Button value={theme} />;
  }
}

useReducer对useState的替代

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

// 官方示例

const initialState = {count: 0};

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, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

useRef获取实时渲染组件的值

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

function TIB() {
  const inputEl = useRef(null);
  const onBClick = () => {
    // `current` 指向已挂载到 DOM 上的文本输入元素
    inputEl.current.focus();
    // console.log(inputEl.current.value)
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onBClick}>Focus the input</button>
    </>
  );
}

当然,还有一些扩充Hook,在一些特殊情况才可能用到,这里不涉及状态管理,我就不打算提了,因为Hook已经包含了部分Redux的功能,那么久可以依照Redux的思路进行项目的状态管理。Hook的出现对react-redux造成了影响,但是不会完全取代。