react - redux 基础
主要目录结构
src
└── reducers
├─ actions
│ └── actions.jsx // 修改方法及类型
├─ module // 模块
│ └── loading.jsx // 初始化
├─ reducers.js // combineReducers 绑定模块
│
main.jsx // 入口
数据共享
以改变 loading
状态为例
创建 Store
文件位置: main.jsx
创建 sotre
, 引入 reducers
, 然后传入 store
javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import { legacy_createStore as createStore, compose, applyMiddleware, combineReducers } from 'redux';
import { thunk } from 'redux-thunk';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import reducers from './reducers/reducers.js';
import App from './App.jsx'
import './index.css'
import '@/assets/css/global.css'
/** --- 核心 -- */
const store = createStore(
combineReducers(reducers),
compose(applyMiddleware(thunk))
);
/** --- 核心 -- */
ReactDOM.createRoot(document.getElementById('root')).render(
(<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>)
);
声明 action type 和 function
文件位置: /src/reducers/actions/actions.js
javascript
/**
* @name action type
*/
export const SET_LOADING = 'SET_LOADING';
/**
* @name action fuction
*/
export const setLoading = (flag) => ({
type: SET_LOADING,
flag
})
写模块
文件位置: /src/reducers/module/loading.js
javascript
import { SET_LOADING } from "/src/reducers/actions/actions.js";
const initState = {
isLoading: false
};
function changeLoading(state = initState, action) {
switch (action.type) {
case SET_LOADING:
return {
...state,
isLoading: action.flag
}
default:
return { ...state };
}
}
export default changeLoading
reducers 中引入
javascript
import { combineReducers } from "redux";
import loading from './module/loading';
const reducers = combineReducers({
loading
});
export default reducers
在页面中获取 - 存储的值 (mapStateToProps)
- 先在页面中导入
connect
和action
文件 - 使用
connect
将store
中的值传递给页面 - 使用
mapStateToProps
将store
中的值映射到页面中的props
中 (别忘了底部的export default connect(mapStateToProps)(Layout)
) - 在页面中通过
this.props
来获取值
javascript
import { connect } from "react-redux";
import { setLoading } from '@/reducers/actions/actions'
const mapStateToProps = (state) => {
return {
isLoading: state.loading.isLoading
}
}
class Layout extends React.Component {
render() {
console.log(this.props.isLoading, '----this.state.isLoading')
}
}
export default connect(mapStateToProps)(Layout)
在页面中修改值 (mapDispatchToProps)
javascript
import { connect } from "react-redux";
const mapDispatchToProps = (dispatch) => {
return {
setLoading: (flag) => dispatch(setLoading(flag))
}
}
class NavBar extends React.Component {
const updateFun = () => {
// 修改值
this.props.setLoading(true)
}
render() {
return (
<div onClick={updateFun}></div>
)
}
}
export default connect(mapDispatchToProps)(NavBar)
connect (两种写法)
第一种
引入 mapStateToProps
和 mapDispatchToProps
,且在结尾 export
时,需要用 connect
进行关联
javascript
const mapStateToProps = (state) => {
return {}
}
const mapDispatchToProps = (dispatch) => {
return {}
}
export default connect(mapStateToProps, mapDispatchToProps)
第二种
通过 @connect
进行关联
javascript
import { connect } from "react-redux";
@connect(
state => ({ '属性值': state.xxx.xxx }),
{ 'action fuction' }
)
TIP
这里要注意的是,使用 @connect 方法,需要预先安装 装饰器 相关插件