框架原理第 4 / 7 章
React Redux
把 Store 接入组件树,并处理同步、异步与模块化 Reducer。
react-redux
- 把react和redux结合起来,封装提供高阶组件的函数,方便使用
使用步骤:
全局提供store
// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './pages/App';
import { Provider } from 'react-redux'
import store from './store'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
在组件中使用,同步action
// component
// 在组件内使用,通过connect高阶函数,传递所需要的state和会触发的dispatch
//函数组件
import React from 'react'
import { connect } from 'react-redux'
import { addNumberAction, subNumberAction } from '../store/actionCreator'
export const About = (props) => {
const { count, addCount, subCount } = props
return (
<div>
<div> count: {count}</div>
<button onClick={e => addCount(1)}>+</button>
<button onClick={e => subCount(1)}>-</button>
</div>
)
}
const mapStateToProps = (state) => ({ count: state.count })
const mapDispatchToProps = (dispatch) => ({
addCount: (num) => dispatch(addNumberAction(num)),
subCount: (num) => dispatch(subNumberAction(num))
})
export default connect(mapStateToProps, mapDispatchToProps)(About)
// 类组件
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { addNumberAction, subNumberAction } from '../store/actionCreator'
export class Home extends Component {
render() {
const { count, addCount, subCount } = this.props
return (
<div>
<div>Home</div>
<div> count: {count}</div>
<button onClick={e => addCount(1)}>+</button>
<button onClick={e => subCount(1)}>-</button>
</div>
)
}
}
const mapStateToProps = (state) => ({ count: state.count })
const mapDispatchToProps = (dispatch) => ({
addCount: (num) => dispatch(addNumberAction(num)),
subCount: (num) => dispatch(subNumberAction(num))
})
export default connect(mapStateToProps, mapDispatchToProps)(Home)
异步action
需要使用中间件增强,redux-thunk
// 安装中间件 redux-thunk,并使用
import { createStore, applyMiddleware } from "redux";
import reducer from "./reducer";
import { thunk } from "redux-thunk";
export const store = createStore(
reducer, applyMiddleware(thunk)
)
export default store
- 编写异步action
//这个action返回一个函数,返回的这个函数会被中间件调用,并传入两个参数,dispatch和getState
//当异步的结果获取的时候,再次dispatch真正的数据过去,这个action还是正常的可以传入参数
export const fetchDataAction = (num) => {
//返回的这个函数会被thunk中间件调用,传递一个dispatch和getState函数进来
return (dispatch, getState) => {
axios.get('').then(res => {
const data = res.data.count
dispatch(addNumberAction(data))
})
}
}
- 组件中派发action
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { addNumberAction, fetchDataAction, subNumberAction } from '../store/actionCreator'
export class Home extends Component {
render() {
const { count, addCount, subCount,fetchCount } = this.props
return (
<div>
<div>Home</div>
<div> count: {count}</div>
<button onClick={e => addCount(1)}>+</button>
<button onClick={e => subCount(1)}>-</button>
<button onClick={e => fetchCount(1)}>fetchCount</button>
</div>
)
}
}
const mapStateToProps = (state) => ({ count: state.count })
const mapDispatchToProps = (dispatch) => ({
addCount: (num) => dispatch(addNumberAction(num)),
subCount: (num) => dispatch(subNumberAction(num)),
fetchCount: (num) => dispatch(fetchDataAction(num))
})
export default connect(mapStateToProps, mapDispatchToProps)(Home)
模块的拆分 - 多个reducer
// 在store创建的时候,使用一个combineReducers去合并不同的reducer,
// 就可以把不同的reducer和action分离出去
// 使用时也需要多家一层key去去取到对应的state
import { createStore, applyMiddleware,combineReducers } from "redux";
import homeReducer from "./reducer";
import { thunk } from "redux-thunk";
const reducer = combineReducers({
home:homeReducer
})
export const store = createStore(
reducer, applyMiddleware(thunk)
)
export default createAsyncThunkstore