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代码总体上会简洁很多!!可读性也很乐观
网友评论