我假设你了解 redux 和 react-redux 的基础知识。简而言之,你知道一个动作被分派到一个商店。
在现实世界中,就好像您更改电视上的频道一样,(1) 您向遥控器发送 CHANGE_CHANNEL 操作,(2) 遥控器将接收发送的操作并发送该操作将频道信息发送到您的电视(减速器),然后 (3) 您的电视(减速器)将与您的有线电视提供商(商店)通信,并在您可用时返回频道数据。
该流程很重要,因为它也可以在您的示例中使用。首先,假设您有一家带有一些探针的商店。在切换您的复选框时,您将发送一个操作 FILTER,例如,它将从数据库列表中过滤掉需要显示的探针,然后使用过滤后的探针调用您的 reducer 以更新您的商店并将该数据发送回您的调度员。
当你第一次加载你的页面时,我也想你想显示所有探测的列表,所以你还需要一个 FETCH 操作来在 componentDidMount 上分派。考虑到这一点,我们可以想出一个这样的类型文件:
types.js
export const TOGGLE_PROBES = "TOGGLE_PROBES";
export const LOAD_PROBES = "LOAD_PROBES";
现在类型已经定义好了,我们可以创建我们的动作了,
import { TOGGLE_PROBES, LOAD_PROBES } from "./types";
const dbProbes = [
{ title: "pa probe 1", type: 1 },
{ title: "pa probe 2", type: 1 },
{ title: "conditional probe 1", type: 2 },
{ title: "conditional probe 1", type: 2 }
];
function toggleProbes(filtered) {
return {
type: TOGGLE_PROBES,
filtered: filtered
};
}
function loadProbes(probes) {
return {
type: LOAD_PROBES,
probes: probes
};
}
export function fetchProbes() {
return function(dispatch) {
dispatch(loadProbes(dbProbes));
};
}
export function filterProbes(filter) {
return function(dispatch) {
const filtered = dbProbes.filter(probe => filter.includes(probe.type));
dispatch(toggleProbes(filtered));
};
}
请注意,我创建了一个名为 dbProbes 的虚假探测器列表。在现实世界中,您可能会访问数据库来过滤您的探测。
设置完所有动作后,您终于可以在 reducer 上工作并相应地更新您的状态,
import { TOGGLE_PROBES, LOAD_PROBES } from "./types";
const initialState = {
probes: []
};
function ButtonReducer(state = initialState, action) {
switch (action.type) {
case TOGGLE_PROBES:
return { ...state, probes: action.filtered };
case LOAD_PROBES:
return { ...state, probes: action.probes };
default:
return state;
}
}
export default ButtonReducer;
为了能够在您的组件中调度它,您确实需要设置 redux。在你的 index.js 中,你可以同时使用 react、react-redux 和 react-thunk 来实现。 React-thunk 是一个中间件,通常与 redux 一起用于异步调用。
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import "./styles.css";
import Buttons from "./Buttons";
import rootReducer from "./store/reducer";
const store = createStore(rootReducer, applyMiddleware(thunk));
const rootElement = document.getElementById("root");
ReactDOM.render(
<Provider store={store}>
<Buttons />
</Provider>,
rootElement
);
首先,在您的 Button 组件中,您可能只想先显示初始列表,因此您需要使用名为 connect 的 react-redux 高阶组件,顾名思义,它将连接您的商店并将商店的状态映射到调度程序和道具。
import React, { Component } from "react";
import ToggleButtonGroupControlled from "./ToggleButtonGroupControlled";
import { connect } from "react-redux";
import { fetchProbes } from "./store/action";
export class Buttons extends Component {
componentDidMount() {
this.props.fetchProbes();
}
render() {
let probes = null;
if (this.props.probes) {
probes = this.props.probes.map(probe => <li>{probe.title}</li>);
}
return (
<div>
<ToggleButtonGroupControlled />
<ul>{probes}</ul>
</div>
);
}
}
function mapStateToProps(state) {
return {
probes: state.probes
};
}
function mapDispatchToProps(dispatch) {
return {
fetchProbes: () => dispatch(fetchProbes())
};
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Buttons);
最后,您的切换按钮组件可以正确地向您的 actions.js 发送一个 TOGGLE_FILTER 操作,这将过滤探针,然后将操作发送到 reducer,reducer 将更新您的状态并返回更新后的状态,此时是映射到 Button.js 组件中的组件道具。
import React, { useState } from "react";
import { ToggleButtonGroup } from "react-bootstrap";
import { ToggleButton } from "react-bootstrap";
import { connect } from "react-redux";
import { filterProbes } from "./store/action";
function ToggleButtonGroupControlled(props) {
const [value, setValue] = useState([1, 2]);
const toggleChangeHandler = newValue => {
setValue(newValue);
props.filterProbes(newValue);
};
return (
<ToggleButtonGroup
type="checkbox"
value={value}
onChange={e => toggleChangeHandler(e)}
>
<ToggleButton value={1}>PA Probes</ToggleButton>
<ToggleButton value={2}>Convential Probes</ToggleButton>
</ToggleButtonGroup>
);
}
function mapDispatchToProps(dispatch) {
return {
filterProbes: types => dispatch(filterProbes(types))
};
}
export default connect(
null,
mapDispatchToProps
)(ToggleButtonGroupControlled);
redux 很酷的地方在于它允许全局状态,因此您可以从 ToggleButtonGroupControlled 组件调度和更改您的探针列表,但是该存储(探针列表)也可用于您决定连接的其他组件到您的商店,在本例中为 Button.js。
您可以在此处检查正在运行的最终代码并为您的问题做好准备:
要了解有关 redux-thunk 的更多信息,请访问此处:https://github.com/reduxjs/redux-thunk
另外,这里有一本免费的 redux 书籍,您可以快速浏览一下:https://leanpub.com/redux-book