React 官方有說建議使用Hooks來管理你的專案,不過React 也說過不會放棄Class,網上說了一堆Hooks的說法。可是都是複製貼上居多。
Hooks出了好一段時間了,我今天才去了解,谷歌上也給出了很多解決方案了。
我先說說為什麼推薦使用Hooks?
其實hooks的這種寫法也不是很新鮮的事,早在antd的官方文件(類似hooks的元件寫法),哪裡的文件案例就不是我們一般人用的class寫法,導致我很多時候都需要再改寫一次。現在的文件已經由另一個人管理了吧寫法都改回了Class寫法。
原因很簡單,因為寫程式碼寫少了很多。沒有this,沒有生命週期,不需要.bind(this),就這麼簡單。
在React Hooks 裡面我們只需記住兩個常用的方法即可。useState
,useEffect
。用來管理自身狀態使用的。
useState
看就知道使用狀態,只是和以前的寫法有出入的是
const [state,setState] = useState(defaultValue);
複製程式碼
你要類似Get Set的東西給定義好。
useEffect
你可以簡單的看成 componentDidMount
、componentDidUpdate
、componentWillUnmount
這樣一個順序的生命週期結合版。
上面的東西就不說了,自己百度或者谷歌,網上一堆那個計算器的例子。
React-Router 在Hooks 裡面的使用
由於Hooks沒有this這個概念,所以以前使用的this.props.history.push()
和this.props.history.goBack()
這些都無法使用了這型別的JS跳轉。
在這裡我們需要一個第三方的庫use-react-router
import useReactRouter from 'use-react-router';
const {history,location,match} = useReactRouter();
history.goBack()
history.push('')
複製程式碼
其他的Router用法和Route的一模一樣,沒有改變。
Reducers 狀態管理
這個肯定是每個React 都關心的一個點
store.js
import {createStore} from 'redux';
import reducer from './reducers';
export const store = createStore(reducer);
複製程式碼
那reducers.js有什麼呢?
const initialState = {
counter: 0
}
export default function reducer(state = initialState,action){
switch(action.type){
case "INCREMENT":
return {counter: state.counter+1}
case "DECREMENT":
return {counter: state.counter-1}
default:
return state;
}
}
複製程式碼
如果使用react-redux
只要將component(也就是Counter)放在Provider之內,就可以在Counter裡面讀取Redux Store。 再用connect把Counter串在一起才能把store傳抵。
在Hooks建議使用
Redux-React-Hooks
import * as React from 'react';
import {StoreContext} from 'redux-react-hook';
import ReactDOM from "react-dom";
import {store} from './store';
import Counter from './Counter';
ReactDOM.render(
<StoreContext.Provider value={store}>
<Counter name="Sara" />
</StoreContext.Provider>,
document.getElementById("root")
);
複製程式碼
基本上除了Provider一個component及其props需要更改外,其他皆與react-redux的例子無異。
最大的更動,在Counter.js就可以看到,由於redux-react-hooks提供了useMappedState及useDispatch,連線Counter的程式碼可以大大簡化。
import * as React from 'react';
import "./styles.css";
import {useMappedState,useDispatch} from 'redux-react-hook';
export default function Counter(props) {
const counter = useMappedState(state=> state.counter);
const dispatch = useDispatch();
return (
<div>
<h1>
Hello, {props.name}
{counter} times
</h1>
<div>
<button onClick={()=>dispatch({type:"INCREMENT"})}>Increment</button>
<button onClick={()=>dispatch({type:"DECREMENT"})}>Decrement</button>
</div>
</div>
);
}
複製程式碼
一個useMappedState,就扮演了mapStateToProps的角色,使用useDispatch,更可以直接於部件裡使用dispatch,無需任何特殊函式。其中一個更明顯的好處,在於Counter的props沒有依賴任何Redux的功能,因此要寫單元測試(Unit testing)就更為簡單。
Hooks程式碼總體上會簡潔很多!!可讀性也很樂觀