實用的react hook

接觸react-hook已經(jīng)很久了缝彬,用了之后,發(fā)現(xiàn)真的很強大哺眯,記錄一下最近使用的想法

useState

首先接觸到的就是useState
state只是一個狀態(tài)谷浅,但是之前class就需要寫的很大,相比之下族购,寫成hook就簡化了很多

class Age extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      age: 20
    };
  }

  handleOnChange = e => {
    const { name, value } = e.target;
    this.setState({ [name]: value });
  };

  render() {
    return (
      <>
        <div>age: {this.state.age}</div>
        <input name="age" onChange={handleOnChange} />
      </>
    );
  }
}

用了hook之后壳贪,就變得很簡潔了

const Age = () => {
  const [age, setAge] = React.useState(20);

  const handleOnChange = e => {
    const { value } = e.target;
    setAge(value);
  };

  return (
    <>
      <div>age: {age}</div>
      <input name="age" onChange={handleOnChange} />
    </>
  );
};

useEffect

對于useEffect我最初以為是用來替代生命周期,比如componentDidMount寝杖,但是事實證明他真的很強大违施,[name]括號里面的是依賴,依賴一變瑟幕,就會重新執(zhí)行磕蒲,多個依賴就更棒了,如果是用之前的寫法只盹,就要在 componentWillReceiveProps里面寫很多if來比較nextPropsthis.props
而且這個最強大就是可以抽出來辣往,當一個反復利用reuseable的hook

傳入不同的localStorageKey,就可以存不同的數(shù)據(jù)到localStorage殖卑, 這樣就方便重復實用了站削,而且每次value變了,就會自動保存到localStorage

const useLocalStorage = localStorageKey => {
  const [value, setValue] = React.useState(
    localStorage && localStorage.getItem(localStorageKey)
  );

  React.useEffect(() => {
    localStorage && localStorage.setItem(localStorageKey, value);
  }, [value, localStorageKey]);

  return [value, setValue];
};

useRef

有些時候孵稽,會發(fā)現(xiàn)许起,其實數(shù)據(jù)并沒有變化,但是還是觸發(fā)了setState或者是別的callback菩鲜,這樣會導致园细,調(diào)用的函數(shù)太多,從而影響了性能接校,所以比較兩個對象是不是相等猛频,只有當不等,才更新蛛勉,這樣可以減小一點re-render鹿寻。
這時候,就是useRef登場的時候了董习,搭配實用lodash.isEqual, 可以比較大的object

const usePrevious = value => {
  const ref = useRef();

  useEffect(() => {
    ref.current = value;
  }, [value]);

  return ref.current;
};

#使用
const myPreviousState = usePrevious(conditions);
useEffect(() => {
 if (myPreviousState && !_.isEqual(myPreviousState, conditions)) {
        onChange(conditions);
 }
}, [myPreviousState, conditions, onChange ])

useContext

context呢烈和,我之前一直覺得這個東西很高大上,很復雜皿淋,一直不敢用招刹,但是后來發(fā)現(xiàn)恬试,他就是對應上下文,比如傳遞props疯暑,一般都是使用parent傳給child训柴,但是如果,A -> B -> C -> D妇拯,但其實B和C都沒用到幻馁,只有D用到了,那么D要來修改A越锈,就需要再往上傳遞仗嗦,導致B和C一直在反反復復被重新渲染,這時候甘凭,當當當當稀拐,context就可以發(fā)揮很大的作用,在A里面包一下Provider丹弱,然后到D直接用createContextuseContext拿出來就可以用了德撬,這樣代碼也不會忘了忘記中間的B,C的pass props躲胳,看起來也清楚蜓洪,何樂而不為呢

const NameContext = createContext();

const A = () => (
   <NameContext.Provider value={{ username, setUserName }}>
     <B />
   </NameContext.Provider>
);

const Names = () => {
  const { username, setUserName } = useContext(NameContext);

  const { names, onChange } = useNames({ username, setUserName });

  return (
    <div>
      <label>firstName</label>
      <input
        name="firstName"
        value={names && names.firstName}
        onChange={onChange}
      />
      <label>lastName</label>
      <input
        name="lastName"
        value={names && names.lastName}
        onChange={onChange}
      />
    </div>
  );
}; 

useReducer

最后是用到redux, 之前對于redux的理解一直如果當一個對象,要被很多不同的地方共享和修改坯苹,那么放到redux是最合適不過隆檀。但是知道我遇到了,一個嵌套很深的一個object粹湃,要更新里面的某一個字段真的要寫好多好多層刚操,然后我翻到了hook對于useReducer的介紹

Another option is useReducer, which is more suited for managing state objects that contain multiple sub-values.

useReducer is usually preferable to useState when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one. useReducer also lets you optimize performance for components that trigger deep updates because you can pass dispatch down instead of callbacks

現(xiàn)在的reducer是相對于useState而言的,他更加適合復雜的再芋,有很多sub-values的對象的更新

import React, { useEffect, useContext, createContext, useReducer } from "react";
const NameContext = createContext();

const init = initial => {
  return { name: initial };
};

const reducer = (state, action) => {
  switch (action.type) {
    case "firstName":
      return {
        ...state,
        name: {
          firstName: action.payload
        }
      };
    case "lastName":
      return {
        ...state,
        name: {
          lastName: action.payload
        }
      };
    default:
      return state;
  }
};

const useNames = ({ username, setUserName }) => {
  // const [names, setNames] = React.useState(username);
  const [state, dispatch] = useReducer(reducer, username, init);
  const names = state.name;

  const onChange = e => {
    const { name, value } = e.target;
    dispatch({ type: name, payload: value });
  };

  useEffect(() => {
    setUserName(names);
  }, [names, setUserName]);

  return {
    names,
    onChange
  };
};

const Names = () => {
  const { username, setUserName } = useContext(NameContext);
  const { names, onChange } = useNames({ username, setUserName });
  return (
    <div>
      <label>firstName</label>
      <input
        name="firstName"
        value={names && names.firstName}
        onChange={onChange}
      />
      <label>lastName</label>
      <input
        name="lastName"
        value={names && names.lastName}
        onChange={onChange}
      />
    </div>
  );
};

const App = () => {
  const [username, setUserName] = React.useState({
    firstName: "Rachel",
    lastName: "Green"
  });

  return (
    <NameContext.Provider value={{ username, setUserName }}>
      <Names />
    </NameContext.Provider>
  );
};

export default App;

完成了一個簡簡單單的name 表單組


image.png
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市坚冀,隨后出現(xiàn)的幾起案子济赎,更是在濱河造成了極大的恐慌,老刑警劉巖记某,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件司训,死亡現(xiàn)場離奇詭異,居然都是意外死亡液南,警方通過查閱死者的電腦和手機壳猜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來滑凉,“玉大人统扳,你說我怎么就攤上這事喘帚。” “怎么了咒钟?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵吹由,是天一觀的道長。 經(jīng)常有香客問我朱嘴,道長倾鲫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任萍嬉,我火速辦了婚禮乌昔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘壤追。我一直安慰自己磕道,他們只是感情好,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布大诸。 她就那樣靜靜地躺著捅厂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪资柔。 梳的紋絲不亂的頭發(fā)上焙贷,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音贿堰,去河邊找鬼辙芍。 笑死,一個胖子當著我的面吹牛羹与,可吹牛的內(nèi)容都是我干的故硅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼纵搁,長吁一口氣:“原來是場噩夢啊……” “哼吃衅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起腾誉,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤徘层,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后利职,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趣效,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年猪贪,在試婚紗的時候發(fā)現(xiàn)自己被綠了跷敬。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡热押,死狀恐怖西傀,靈堂內(nèi)的尸體忽然破棺而出斤寇,到底是詐尸還是另有隱情,我是刑警寧澤池凄,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布抡驼,位于F島的核電站,受9級特大地震影響肿仑,放射性物質(zhì)發(fā)生泄漏致盟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一尤慰、第九天 我趴在偏房一處隱蔽的房頂上張望馏锡。 院中可真熱鬧,春花似錦伟端、人聲如沸杯道。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽党巾。三九已至,卻和暖如春霜医,著一層夾襖步出監(jiān)牢的瞬間齿拂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工肴敛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留署海,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓医男,卻偏偏與公主長得像砸狞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子镀梭,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353