上面是Count
组件,下面是Flag
组件。
Count
组件中,点击点击+1
按钮,数值加一,点击清零
按钮,数值清零,同时数值传递给Flag
组件同步显示。
Flag
组件中,点击login
可以切换为true
,点击logout
切换为false
,同时将状态传递给Count
组件同步显示。
npm install react-redux redux redux-thunk redux-devtools-extension
使用了redux
,需要在UI组件
外套一层容器组件
。由于是父子关系,容器组件
通过props
向里层的UI组件
传递参数,将容器组件
放在containers
文件夹下。
使用redux
,需要单独创建redux
文件夹,包括actions
文件夹和reducers
文件夹,还有向外暴露常量的constant.js
和store.js
。
(1)组件定义
通过class
定义的是UI组件
,向外暴露的是容器组件
,容器组件
通过props
向UI组件
传递状态和方法。
// src/containers/Count/index.jsx
import React, {
Component, Fragment } from 'react';
import {
connect } from 'react-redux';
import {
add, clear } from '../../redux/actions/count';
// UI组件
class Count extends Component {
add = () => {
// 通知redux
this.props.add(1);
};
clear = () => {
this.props.clear();
};
render() {
return (
<Fragment>
<h2>当前求和为:{
this.props.count}</h2>
<h3>当前Flag:{
this.props.flag ? 'true' : 'false'}</h3>
<button onClick={
this.add}>点击+1</button>
<button onClick={
this.clear}>清零</button>
</Fragment>
);
}
}
// 暴露容器组件
export default connect(
// 1.状态
state => ({
count: state.sum, flag: state.flagState }),
// 2.方法
{
add, clear }
)(Count);
(2)创建action
该文件用于创建action
对象。
// src/redux/actions/count.js
// 为Count组件创建action对象
// 引入常量
import {
ADD, CLEAR } from '../constant';
// 创建加一action对象的函数
export const add = data => ({
type: ADD,
data,
});
// 创建清零action对象的函数
export const clear = data => ({
type: CLEAR,
data,
});
(3)reducer
该文件用于判断type
的类型,加工数据。
// src/redux/reducers/count.js
// 为Count组件创建一个reducer
// reducer接收两个参数:之前状态的preState,动作对象action
import {
ADD, CLEAR } from '../constant.js';
// 设定初始状态
const initState = 0;
export default function addReducer(preState = initState, action) {
// 从action中获取type和data
const {
type, data } = action;
// 根据type决定如何加工数据
switch (type) {
case ADD:
return preState + data;
case CLEAR:
return 0;
// 初始化动作
default:
return preState;
}
}
(1)组件定义
// src/containers/Flag/index.jsx
import React, {
Component, Fragment } from 'react';
import {
connect } from 'react-redux';
import {
login, logout } from '../../redux/actions/flag';
class Flag extends Component {
login = () => {
this.props.login();
};
logout = () => {
this.props.logout();
};
render() {
return (
<Fragment>
<h2>当前Flag:{
this.props.flag ? 'true' : 'false'}</h2>
<h3>当前求和为:{
this.props.count}</h3>
<button onClick={
this.login}>login</button>
<button onClick={
this.logout}>logout</button>
</Fragment>
);
}
}
export default connect(state => ({
flag: state.flagState, count: state.sum }), {
login, logout })(
Flag
);
(2)创建action
// src/redux/actions/flag.js
// 为Flag组件创建action对象
// 引入常量
import {
LOGIN, LOGOUT } from '../constant';
// 创建加一action对象的函数
export const login = data => ({
type: LOGIN,
data,
});
// 创建加一action对象的函数
export const logout = data => ({
type: LOGOUT,
data,
});
(3)reducer
// src/redux/reducers/flag.js
// reducer接收两个参数:之前状态的preState,动作对象action
import {
LOGIN, LOGOUT } from '../constant.js';
// 设定初始状态
const initState = false;
export default function addReducer(preState = initState, action) {
const {
type } = action;
switch (type) {
case LOGIN:
return true;
case LOGOUT:
return false;
default:
return preState;
}
}
所有的组件的reducer
要汇总到一个文件中,并向外暴露redux
中存放的状态对象。
// src/redux/reducers/index.js
// 汇总所有的reducer
import {
combineReducers } from 'redux';
import sum from './count';
import flagState from './flag';
export default combineReducers({
sum,
flagState,
});
// src/redux/constant.js
export const LOGIN = 'login';
export const LOGOUT = 'logout';
export const ADD = 'add';
export const CLEAR = 'clear';
引入汇总后的rudecer
,暴露store
。
// src/redux/store.js
// 整个文档只有一个store对象
import {
createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import allRudecers from './reducers';
import {
composeWithDevTools } from 'redux-devtools-extension';
// 暴露store
export default createStore(allRudecers, composeWithDevTools(applyMiddleware(thunk)));
引入store
,并将
用
包裹,这样
下所有的组件都能接收到store
了。
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
import store from './redux/store';
import {
Provider } from 'react-redux';
ReactDOM.render(
// Provider包裹App,目的:让App所有的后代容器组件都能接收到store
<Provider store={
store}>
<App />
</Provider>,
document.getElementById('root')
);
欢迎在我的博客上访问:
https://lzxjack.top/