React hooks 的嘗試使用

React Hooks出來也已經挺久了,一直苦於沒有機會去嘗試。此次不用不知道,一用嚇一跳,用hooks寫頁面和組件真的是太爽啦!不再用寫冗餘的類,不用維護複雜的state和考慮異步的setState,不用考慮this的指向,不用細想在哪一個生命週期裏執行復雜的邏輯,寫起來只能用行雲流水來形容。若是你還在猶豫要不要使用hooks,請大膽的去嚐鮮吧!(p.s:記得把react升級到16.8版本)html


這裏就不介紹hooks是什麼,只是記錄了一些我在項目裏hooks的一些用法。若是想詳細瞭解hooks的話,我推薦去看官方文檔和一些入門文章react

傳送門:
React-文檔 Hook 簡介
30分鐘精通React Hooks
React16:Hooks總覽,擁抱函數式 (這大概是最全的React Hooks吧)編程


Hooks只能用在純函數組件裏數組

之前組件通訊,要麼使用props一層層傳遞下去,要麼使用Redux等狀態管理架構。這些方法冗餘,繁瑣,易出錯。bash

Hooks的出現,帶給了咱們新的解決這些問題的方法。antd

1.使用useContext實現組件間通訊

import React, { createContext, useContext } from 'react';

// 建立Context  
const Context = createContext(defaultContext);

connt shareContext = {
    name: 'context',
    value: 12,
};

// 頂層組件提供共享值C
<Context.Provider value={shareContext} >
    <ChildrenComponents />
</Context.Provider>

// 子組件經過useContext,和 Context 獲取共享值
function ChildrenComponents() {
    const { name, value } = useContext(Context);
    console.log(name); // 'context'
    console.log(value); // 12
}
複製代碼

2. 使用useReducer管理多個組件之間的狀態

useReducer的基本概念與Redux一致,不瞭解的能夠先去了解一下什麼是action,dispatch,reducer之類的。架構

// actions
const SOME_ACTIONS = 'SOME_ACTIONS';   // 定義action

// reducer
function reducer(state, action) {
    switch(action.type) {
        case SOME_ACTIONS:
            /*handle state with action.payload*/
            return nextState;
        default:
            return state;
    }
}

const iniState = /*初始狀態*/

// 組件裏使用useReducer

fuction Components() {
    const [state, dispatch] = useReducer(reducer, iniState);
    
    /* state 即爲所共享的狀態*/
    
    /* 使用 dispatch 經過指定 action 修改 state 的值*/
    
    dispatch({ type: ACTION_TYPE, payload: SOME_PROPS });
}
複製代碼

3.使用各類hooks實現一個自定義hooks

咱們能夠根據需求設計自定義hooks。注意,自定義hooks必定要以useXXX的格式命名。具體緣由可到官方文檔去了解:Building Your Own Hooksapp

3.1 實現一個即插即用彈窗(基於antd Modal組件)

之前咱們使用Modal組件,老是要本身維護一套state來控制Modal的visible,onCancel等設計比較固定的屬性,帶來冗餘代碼和形態萬千的實現。並且須要提早引入組件,這會形成某些奇怪的問題和沒必要要的渲染。異步

// 控制Modal生命週期的hooks:

// 組件的惟一id, 包裹組件的div, 組件props,回調函數
function useModal(id = '__YOU_SHOULD_PROVIDE_AN_ID', WrapDiv, dataProps) {
  const [visible, setVisible] = useState(false);

  function showModal() {
    setVisible(true);
  }

  function destroy() {
    const unmountResult = ReactDOM.unmountComponentAtNode(WrapDiv);
    if (unmountResult && WrapDiv.parentNode) {
      WrapDiv.parentNode.removeChild(WrapDiv);
    }
  }

  function closeModal() {
    setVisible(false);
    destroy();
  }

  return [showModal, {
    key: id,
    visible,
    onCancel: closeModal,
    ...dataProps,
  }];
}

function DirectiveModal({ DirectModal, id, WrapDiv, ...props }) {
  const [showModal, ModalProps] = useModal(id, WrapDiv, props);

  useEffect(() => {
    showModal();
  }, []);

  return (
    <DirectModal {...ModalProps} />
  );
}

DirectiveModal.propTypes = {
  id: PropTypes.string,
  DirectModal: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
  WrapDiv: PropTypes.object,
  props: PropTypes.any,
  callback: PropTypes.func,
};

function createDirectiveModal(DirectModal, props) {
  const WrapDiv = document.createElement('div');
  document.querySelector('#app').appendChild(WrapDiv);

  function render() {
    ReactDOM.render(
      <DirectiveModal
        DirectModal={DirectModal}
        WrapDiv={WrapDiv}
        {...props}
      />,
      WrapDiv
    );
  }

  render();
}

export default createDirectiveModal;
複製代碼

4. 總結

靈活組合使用hooks能使咱們編程更便利,代碼邏輯更加清晰高效。自定義hooks帶來的可拓展性更是潛力無窮。也難怪當初hooks出來的時候引爆互聯網了。心動的快趕快把你的React升級到16.8,去體驗hooks的無窮魅力吧!ide

相關文章
相關標籤/搜索