react-redux使用及源码分析(上)
一、为何使用react-redux
使用原生 redux,需要在页面中手动获取state和手动触发action,并且还要自己订阅,以便在state发生变化时重新渲染视图。
使用react-redux可以将state和触发action的方法,作为props传给组件,并且会自动订阅,props改变就自动渲染视图了。
二、如何使用react-redux
使用react-redux,有以下几个步骤:
1、使用 redux 创建一个 store
import { createStore } from "redux";
// 定义默认state
const defaultState = {
count: 0
};
// 定义 reducer
function countReducer(state = defaultState, action) {
switch (action.type) {
case "ADD": {
const newState = Object.assign({}, state);
newState.count += action.payload || 1;
return newState;
}
case "MINUS":
const newState = Object.assign({}, state);
newState.count -= action.payload || 1;
return newState;
default:
return state;
}
}
// 创建一个数据仓库
const store = createStore(countReducer);
export default store;
2、使用react-redux的Provider组件包裹项目的根组件
import { Provider } from "react-redux";
import ConnectCounter from "./pages/Counter";
import store from "./store";
export default function App() {
return (
<Provider store={store}>
<ConnectCounter />
</Provider>
);
}
这样,在Provider中的组件都可以访问到 store 了
3、编写一个普通的组件,然后使用 react-redux 的 connect 函数将其进行“强化”
import React from "react";
import { connect } from "react-redux";
function mapStateToProps(state) {
return {
value: state.count
};
}
function mapDispatchToProps(dispatch) {
return {
onAdd: () => dispatch({ type: "ADD" }),
onMinus: () => dispatch({ type: "MINUS" })
};
}
class Counter extends React.Component {
render() {
console.log("counter render", this.props);
const { value, onAdd, onMinus } = this.props;
return (
<div>
<h3>Counter</h3>
<p>count: {value}</p>
<button onClick={onAdd}>ADD</button>
<button onClick={onMinus}>MINUS</button>
</div>
);
}
}
const ConnectCounter =
connect(mapStateToProps, mapDispatchToProps)(Counter);
export default ConnectCounter;
connect
函数需要两个参数:mapStateToProps
和 mapDispatchToProps
,这两个参数也是一个函数,参数分别为 state 和 dispatch;返回值为一个对象,对象的键名就作为 Counter 组件的一个props属性。connect
函数返回一个高阶组件,高阶组件其实就是一个函数,接收组件为参数,并返回一个新的组件。在上述代码中就是 ConnectCounter 组件。
三、如何在函数组件中用hooks的方式使用 react-redux
同样需要用redux创建store,使用Provider包裹子组件,只是编写组件时可以使用react-redux提供的两个hook来使用state和dispatch
import React, { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
export default function TestReduxHooks() {
const count = useSelector((state) => state.count);
const dispatch = useDispatch();
return (
<div>
<div>
<p>count: {count}</p>
<button onClick={() => dispatch({ type: "ADD" })}>
Increment
</button>
<button onClick={() => dispatch({ type: "MINUS" })}>
Decrement
</button>
</div>
</div>
);
}
上述代码使用 useSelector
来获取state,使用 useDispatch
来获取 dispatch 方法,以触发action。
使用 hooks 的方式比 connect 节省更多代码,更加简洁,推荐使用。
本节主要介绍 react-redux 的使用,下节介绍其源码实现。