为什么用react-redux?
- redux与react组件的代码耦合度太高
- 编码不够简洁
基本概念
React-Redux将所有组件分成两大类
?UI组件
a.只负责 UI 的呈现,不带有任何业务逻辑
b.通过props接收数据(一般数据和函数)
c.不使用任何 Redux 的 API
d.一般保存在components文件夹下
容器组件
a.负责管理数据和业务逻辑,不负责UI的呈现
b.使用 Redux 的 API
c.一般保存在containers文件夹下
相关API
1.Provider
让所有组件都可以得到state数据
<Provider store={store}> ????<App /> ??</Provider>
2.connect()
用于包装?UI 组件生成容器组件
import { connect } from 'react-redux' ??connect( ????mapStateToprops, ????mapDispatchToProps ??)(Counter)
3.mapStateToprops()
将外部的数据(即state对象)转换为UI组件的标签属性 ??const mapStateToprops = function (state) { ???return { ?????value: state ???} ??}
4.mapDispatchToProps()
将分发action的函数转换为UI组件的标签属性
简洁语法可以直接指定为actions对象或包含多个action方法的对象
下载包 npm install --save react-redux
优化redux:根据?React-Redux组件分类思想,将app.jsx从上一篇的redux内抽离出来
// app.jsx
import { connect } from "react-redux";
// 引入action内的方法
import { increment, decrement } from "../redux/actions";
// 引入容器组件
import counter from "../components/counter";
export default connect(
(state) => {
// state为store内的count值 即0
console.log(state, "state");
// 将state状态传给counter组件
return { count: state };
},
// 将increment,decrement方法传给counter
{ increment, decrement }
)(counter);
// counter.js内
// 导入 React 模块
import React, { Component } from "react";
import propTypes from "prop-types";
// 暴露并创建react类
export default class App extends Component {
static propTypes = {
count: propTypes.number.isRequired,
increment: propTypes.func.isRequired,
decrement: propTypes.func.isRequired,
};
addCountFn = () => {
this.props.increment(this.select.value * 1);
};
delCountFn = () => {
this.props.decrement(this.select.value * 1);
};
incrementOddFn = () => {
const { count } = this.props;
if (count % 2 === 1) {
this.props.increment(this.select.value * 1);
}
};
incrementAsyncFn = () => {
setTimeout(() => {
this.props.increment(this.select.value * 1);
}, 1000);
};
render() {
const { count } = this.props;
return (
<div>
<h2>click {count} times</h2>
<select ref={(select) => (this.select = select)}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button onClick={this.addCountFn}>+</button>
<button onClick={this.delCountFn}>-</button>
<button onClick={this.incrementOddFn}>increment if odd</button>
<button onClick={this.incrementAsyncFn}>increment async</button>
</div>
);
}
}
// index.js
import React from "react";
import { createRoot } from 'react-dom/client';
import { Provider } from "react-redux";
import store from './redux/store'
import App from "./containers/app";
createRoot(document.getElementById('root')).render(
<Provider store={store} >
<App />
</Provider>
);;
上一篇问题:reducers.js如何暴露多个模块
?// reducers.js
import { COMMENT_ADD, COMMENT_DEL, COMMENT_INIT, INCREMENT, DECREMENT } from "./action-types";
import { combineReducers } from 'redux'
const initCommentData = []
function comments (state = initCommentData, actions) {
switch (actions.type) {
// 添加方法
case COMMENT_ADD:
return [actions.data, ...state]
// 删除方法
case COMMENT_DEL:
return state.filter((comment, index) => index !== actions.data)
// 初始化评论
case COMMENT_INIT:
return actions.data
// 默认
default:
return state
}
}
function counter (state = 0, action) {
switch (action.type) {
case INCREMENT:
return state += action.data
case DECREMENT:
return state -= action.data
default:
return state
}
}
export default combineReducers(
{
comments,
counter
}
)
暴露多个模块后,相应的组件 也要做修改
// app.jsx
import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import Add from "../../components/commentAdd/commentAdd";
import List from "../../components/commentList/commentList";
import { commentAdd, commentDel, commentAsync } from "../../redux/actions";
import "./app.css";
class App extends Component {
static propTypes = {
commentList: PropTypes.array.isRequired,
commentAdd: PropTypes.func.isRequired,
commentDel: PropTypes.func.isRequired,
commentAsync: PropTypes.func.isRequired,
};
componentDidMount() {
const { commentAsync } = this.props;
commentAsync();
}
render() {
const { commentList, commentAdd, commentDel } = this.props;
return (
<div id="app">
<div>
<header className="site-header jumbotron">
<div className="container">
<div className="row">
<div className="col-xs-12">
<h1>请发表对React的评论</h1>
</div>
</div>
</div>
</header>
<div className="container">
<Add commentAdd={commentAdd} />
<List commentList={commentList} commentDel={commentDel} />
</div>
</div>
</div>
);
}
}
export default connect((state) =>
// 此处为reducers修改后调整
({ commentList: state.comments }),
{
commentAdd,
commentDel,
commentAsync
}
)(App);
// store.js 存储 状态变量
import { configureStore } from '@reduxjs/toolkit'
import reducers from './reducers'
// 根据comments函数创建store对象
const store = configureStore({ reducer: reducers })
console.log(store, 'store');
export default store
?
redux如何处理异步操作???
redux-thunk处理异步操作_FF_XM的博客-CSDN博客
redux基本概念
redux初体验(问题记录)_FF_XM的博客-CSDN博客
|