React Hooks 自推出以後,收到了很多追捧, 不少問題也隨之而來。javascript
本文就其中的一個話題展開討論:React Hooks 是否會取代傳統的Redux ?
css
我認爲: 不會
.html
在我看來,相比於傳統的Class Component, Hooks 並無提供什麼新的狀態功能,只不過是對原有的 API 作了加強。java
相比以前,Hoos 更加簡潔,也提高了原生 API 的可用性,適用的場景也愈來愈多。react
爲了闡明個人觀點, 咱們先作一些回顧。編程
Redux 是一個 可預測的狀態管理工具
,能夠輕鬆集成在 React 應用中。 它有不少優勢, 好比:redux
時光機
總的來講, Redux 提供了應對大型應用的代碼組織和調試能力,在程序出錯時, 能幫你快速定位問題。segmentfault
在下的這邊文章科普了Hooks的一些基礎功能, 感興趣的能夠看一下。api
[全面瞭解 React 新功能: Suspense 和 Hooks ][segmentfault.com/a/119000001…]bash
Hooks 的主要優勢:
兩家各有所長,好在如今有 react-redux Hooks(react-redux.js.org/next/api/ho…) 和 Reducer Hook (reactjs.org/docs/hooks-…) 這樣的工具,咱們就沒有必要糾結二者之間如何選擇,雨露均沾, 美滋滋。
拋棄生命週期方
法, 擁抱Hooks。Render Props
這種模式也有了更好的歸宿Redux
HOC
容器組件
和視圖組件
之間的隔離, 分離純邏輯和視覺效果, 更易於測試。任什麼時候候你均可以使用Redux 來管理狀態,只要你喜歡。 可是若是你的應用足夠簡單,只包含單個視圖,須要一個地方臨時保存狀態,不須要和其餘組件共享數據,或者甚至都沒有異步I/O都沒有(有也無所謂)。 這時候就到Hooks大顯身手了,這些情景下用Redux, 固然也能夠,不過這種作法叫用牛刀殺雞雞。
來看個例子:
import React, { useState } from 'react';
import t from 'prop-types';
import TextField, { Input } from '@material/react-text-field';
const noop = () => {};
const Holder = ({
itemPrice = 175,
name = '',
email = '',
id = '',
removeHolder = noop,
showRemoveButton = false,
}) => {
const [nameInput, setName] = useState(name);
const [emailInput, setEmail] = useState(email);
const setter = set => e => {
const { target } = e;
const { value } = target;
set(value);
};
return (
<div className="row">
<div className="holder">
<div className="holder-name">
<TextField label="Name">
<Input value={nameInput} onChange={setter(setName)} required />
</TextField>
</div>
<div className="holder-email">
<TextField label="Email">
<Input
value={emailInput}
onChange={setter(setEmail)}
type="email"
required
/>
</TextField>
</div>
{showRemoveButton && (
<button
className="remove-holder"
aria-label="Remove membership"
onClick={e => {
e.preventDefault();
removeHolder(id);
}}
>
×
</button>
)}
</div>
<div className="line-item-price">${itemPrice}</div>
<style jsx>{cssHere}</style>
</div>
);
};
export default Holder;
複製代碼
上面的例子 使用 useState 來跟蹤表單中的 name
和 email
:
const [nameInput, setName] = useState(name);
const [emailInput, setEmail] = useState(email);
複製代碼
你可能會注意到還有一個 removeHolder ,這個action creator 來自 Redux 。這種模式下,各類方法均可以混合搭配。
在 Hooks 出現以前, 可使用 local state 保存狀態和更新狀態 用以應對這種狀況。若是是我寫這個的話, 我更傾向於把它塞到Redux中, 再經過Prop去取狀態吧。
反正到如今, 我作過的全部React應用, 都用到了Redux,原則也很簡單:
組件狀態用組件狀態,應用狀態用 Redux。 各司其職, 相得益彰。
另外一個常見的疑問是, 我應該把全部的數據和狀態都放在Redux嗎?
若是不這麼作的話, 是否是就沒法使用時間旅行?
答案是不會的。
由於應用中有不少狀態是臨時的,種種侷限不足覺得日誌遙測或者時間旅行提供足夠多的信息。 除非你在作的是一個具備協同能力的文本編輯器(好比我以前參與的Lark Docs, 還有騰訊文檔等),能夠把用戶的每個操做,每個changeSet 的數據都保存起來, 包括光標位置等信息。
每次你往Redux 裏添加數據的時候, 隨之而來的是一層抽象和額外的複雜度。
換言之, 每次你要用Redux的時候, 要知道本身爲啥須要用到它。 若是你的應用有以下需求, 那就能夠考慮使用Redux:
仍是那個例子:
訪問連接: tddday.com/
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { compose } from 'ramda';
import page from '../../hocs/page.js';
import Purchase from './purchase-component.js';
import { addHolder, removeHolder, getHolders } from './purchase-reducer.js';
const PurchasePage = () => {
// You can use these instead of
// mapStateToProps and mapDispatchToProps
const dispatch = useDispatch();
const holders = useSelector(getHolders);
const props = {
// Use function composition to compose action creators
// with dispatch. See "Composing Software" for details.
addHolder: compose(
dispatch,
addHolder
),
removeHolder: compose(
dispatch,
removeHolder
),
holders,
};
return <Purchase {...props} />;
};
// `page` is a Higher Order Component composed of many
// other higher order components using function composition.
export default page(PurchasePage);
複製代碼
這個組件並不處理任何DOM, 是一個純展現型的組件,並用 React-Redux hooks API 鏈接到 Redux 上。
之因此用到 Redux,是由於其餘部分須要這個表單的數據。它的狀態不是本地化到單個組件中,而是在組件之間共享;
Redux 容許咱們乾淨地將反作用與其餘組件邏輯分離開來,不須要咱們模擬 I/O 服務。
相比 redux-thunk,我更喜歡使用 redux-saga 的緣由就是後者的隔離功能)。
爲了在這個用例上追趕 Redux 的腳步,React 的 API 須要提供反作用隔離功能。
Redux 與狀態管理庫有着很大區別。但本質上,也是 Flux 架構 的一個子集。
與庫相比,Redux 向來更接近一種架構和非強制性的約定(convention)。
事實上,Redux 的基本實現只須要幾十行代碼。
這也是 Redux 的一大好處。若是你想多用一些本地組件狀態和 hook API,不想把全部內容都塞到 Redux 裏,那也徹底沒問題。
React 提供了一個 useReducer hook,能夠用它接入你的 Redux 風格的 Reducer。這對不常見的狀態邏輯、依賴狀態等內容很是有用。
若是你的用例是要將臨時狀態裝入單個組件,也可使用 Redux 架構,但要用 useReducer hook 取代 Redux 來管理狀態。
若是你後面須要維持或共享這個狀態, 就須要把它保存到Redux裏了。
Hooks 並不會替代傳統的 Redux, 它的出現爲咱們編寫組件提供了更多的靈活性, 更多的可能, 但願各位FEer 都能及時擁抱這個新特性, 找到本身最喜歡的開發姿式~
行文粗淺, 如有疏漏, 還請指正。
附原文連接: medium.com/javascript-…