Javascript Redux Store将重复内容和导航添加到原始选择并生成空数组
我正在尝试为我的React应用程序实现Redux数据存储和URL路由,我遇到了(2)个问题: 1.)我有一个下拉菜单,每当我选择原始选择(由我导航到的URL定义)时,数据存储将生成一个空数组。例如,如果我导航到http://localhost:3001/dash/programs/all,从下拉列表中选择“足球”,然后从下拉列表中选择“全部”。数据数组输出将为[],图表将不输出可视化 2.)当我从下拉列表中选择一个项目,然后再次选择它时,数据会连接起来,图表会显示两次数据。例如,如果我单击Soccer并再次单击Soccer,则阵列将具有重复数据 这是我的档案: DataStore.jsJavascript Redux Store将重复内容和导航添加到原始选择并生成空数组,javascript,reactjs,redux,react-router-dom,Javascript,Reactjs,Redux,React Router Dom,我正在尝试为我的React应用程序实现Redux数据存储和URL路由,我遇到了(2)个问题: 1.)我有一个下拉菜单,每当我选择原始选择(由我导航到的URL定义)时,数据存储将生成一个空数组。例如,如果我导航到http://localhost:3001/dash/programs/all,从下拉列表中选择“足球”,然后从下拉列表中选择“全部”。数据数组输出将为[],图表将不输出可视化 2.)当我从下拉列表中选择一个项目,然后再次选择它时,数据会连接起来,图表会显示两次数据。例如,如果我单击Soc
import { createStore } from "redux";
import { DataReducer } from "./DataReducer";
export const DashDataStore = createStore(DataReducer);
Types.js
export const DataTypes = {
RELEASE_FREQUENCY_DATA: "release_frequency_data",
PROGRAMS: "programs"
};
export const ActionTypes = {
DATA_LOAD: "data_load"
};
ActionCreators.js
import { ActionTypes } from "./Types";
import { data as phData } from "./placeholderData";
export const loadData = (dataType) => ({
type: ActionTypes.DATA_LOAD,
payload: {
dataType: dataType,
data: phData[dataType]
}
});
DataReducer.js
import { ActionTypes } from "./Types";
export const DataReducer = (storeData, action) => {
switch(action.type) {
case ActionTypes.DATA_LOAD:
return {
...storeData,
[action.payload.dataType]: action.payload.data
};
default:
return storeData || {};
}
};
ProgramNavigation.js
import React, { Component } from "react";
import { ToggleLink } from "../ToggleLink";
export class ProgramNavigation extends Component {
render() {
return <React.Fragment>
<div className = "dropdown">
<button className = "btn btn-secondary dropdown-toggle" type="button" id="programDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Select Program
</button>
<div className = "dropdown-menu" aria-labelledby="programDropdown">
{ this.props.programs && this.props.programs.map(cat =>
<ToggleLink className="dropdown-item" href = "#" key = { cat }
to={ `${this.props.baseUrl}/${cat.toLowerCase()}`}>
{ cat }
</ToggleLink>
)}
</div>
</div>
</React.Fragment>
}
}
问题与过滤器功能有关。数据的解析方式存在问题,需要进行以下更改: 原创的
const filterReleaseFrequency = (release_frequency_data = [], program) =>
release_frequency_data.filter(p => p.program.toLowerCase() === program.toLowerCase());
新的
import React, { Component } from "react";
import { Switch, Route, Redirect } from "react-router-dom";
import { connect } from "react-redux";
import { loadData } from "../data/ActionCreators";
import { DataTypes } from "../data/Types";
import { OutcomeCard} from "../outcomes/OutcomeCard";
const mapStateToProps = (dataStore) => ({
...dataStore
});
const mapDispatchToProps = {
loadData
};
const filterReleaseFrequency = (release_frequency_data = [], program) =>
release_frequency_data.filter(p => p.program.toLowerCase() === program.toLowerCase());
export const DataConnector = connect(mapStateToProps, mapDispatchToProps)(
class extends Component {
render() {
return <Switch>
<Route path="/dash/programs/:program?"
render={ (routeProps) =>
<OutcomeCard { ...this.props } { ...routeProps }
release_frequency_data={ filterReleaseFrequency(this.props.release_frequency_data,
routeProps.match.params.program) } />} />
<Redirect to="/dash/programs/all" />
</Switch>
}
componentDidMount() {
this.props.loadData(DataTypes.RELEASE_FREQUENCY_DATA);
this.props.loadData(DataTypes.PROGRAMS);
}
}
);
import React, { Component } from "react";
import { Route, Link } from "react-router-dom";
export class ToggleLink extends Component {
render() {
return <Route path={ this.props.to } exact={ this.props.exact }
children = { routeProps => {
const baseClasses = this.props.className || "dropdown-item";
const activeClass = this.props.activeClass || "dropdown-item active";
const inActiveClass = this.props.inActiveClass || "dropdown-item";
const combinedClasses =
`${baseClasses} ${routeProps.match ? activeClass : inActiveClass}`
return <Link to={ this.props.to } className={ combinedClasses }>
{ this.props.children }
</Link>
}} />
}
};
import React, { Component } from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
export class ChartRender extends Component {
render() {
const chartOptions = {
chart: {
height: 300,
width: 700,
backgroundColor: "#071f3b",
type: 'spline'
},
title: {
text: null
},
yAxis: {
title: {
"text": null
},
plotLines: [
{
color: "yellow",
value: 42.0977,
dashStyle: "shortdash",
width: 2,
zIndex: 100,
label: {
text: "TARGET",
align: "left",
x: 0,
y: 15,
style: {
color: "yellow",
zIndex: 10,
fontSize: ".6rem"
}
}
}
],
gridLineColor: "transparent",
labels: {
style: {
color: "white",
fontSize: ".6rem"
}
}
},
plotOptions: {
series: {
label: {
enabled: false
}
},
column: {
animation: {
duration: 1600
}
}
},
xAxis: {
type: "datetime",
labels: {
style: {
color: "white",
fontSize: ".6rem"
}
}
},
series: [{
name: "Chart Title",
data: this.props.release_frequency_data
}],
legend: {
enabled: false,
}
};
return (
<div style={{width: 'inherit', textAlign: 'center'}}>
<HighchartsReact highcharts={Highcharts} options={chartOptions}/>
</div>
)
}
};
import React, { Component } from 'react';
import { DashDataStore } from "./data/DataStore";
import { Provider } from "react-redux";
import { BrowserRouter as Router, Route, Switch, Redirect } from "react-router-dom";
import { DataConnector } from "./outcomes/DataConnector";
import Highcharts from "highcharts";
Highcharts.setOptions({
credits:{
enabled: false
}
});
export default class App extends Component {
render() {
return <Provider store = { DashDataStore }>
<Router>
<Switch>
<Route path="/dash" component = { DataConnector } />
<Redirect to="/dash" />
</Switch>
</Router>
</Provider>
}
}
export const data = {
programs: ["Soccer", "Baseball", "Football", "All"],
release_frequency_data: [
{
"x": 1577854800000,
"y": 72.5918,
"color": "#fc0303",
"program": "Soccer"
},
{
"x": 1580533200000,
"y": 28.2154,
"color": "#0bfc03",
"program": "Soccer"
},
{
"x": 1583038800000,
"y": 43.2504,
"color": "#fc0303",
"program": "Soccer"
},
{
"x": 1585713600000,
"y": 24.7519,
"color": "#0bfc03",
"program": "Soccer"
},
{
"x": 1588305600000,
"y": 85.1896,
"color": "#fc0303",
"program": "Soccer"
},
{
"x": 1590984000000,
"y": 77.4816,
"color": "#fc0303",
"program": "Soccer"
},
{
"x": 1593576000000,
"y": 11.1693,
"color": "#0bfc03",
"program": "Soccer"
},
{
"x": 1596254400000,
"y": 15.9701,
"color": "#0bfc03",
"program": "Soccer"
},
{
"x": 1598932800000,
"y": 28.0714,
"color": "#0bfc03",
"program": "Soccer"
},
{
"x": 1601524800000,
"y": 4.4327,
"color": "#0bfc03",
"program": "Soccer"
},
{
"x": 1604203200000,
"y": 98.512,
"color": "#fc0303",
"program": "Soccer"
},
{
"x": 1606798800000,
"y": 15.5359,
"color": "#0bfc03",
"program": "Soccer"
},
{
"x": 1577854800000,
"y": 80.9702,
"color": "#fc0303",
"program": "Baseball"
},
{
"x": 1580533200000,
"y": 76.2792,
"color": "#fc0303",
"program": "Baseball"
},
{
"x": 1583038800000,
"y": 63.0659,
"color": "#fc0303",
"program": "Baseball"
},
{
"x": 1585713600000,
"y": 28.0056,
"color": "#0bfc03",
"program": "Baseball"
},
{
"x": 1588305600000,
"y": 24.414,
"color": "#0bfc03",
"program": "Baseball"
},
{
"x": 1590984000000,
"y": 8.6725,
"color": "#0bfc03",
"program": "Baseball"
},
{
"x": 1593576000000,
"y": 92.8561,
"color": "#fc0303",
"program": "Baseball"
},
{
"x": 1596254400000,
"y": 1.7665,
"color": "#0bfc03",
"program": "Baseball"
},
{
"x": 1598932800000,
"y": 98.9164,
"color": "#fc0303",
"program": "Baseball"
},
{
"x": 1601524800000,
"y": 22.7252,
"color": "#0bfc03",
"program": "Baseball"
},
{
"x": 1604203200000,
"y": 35.0828,
"color": "#0bfc03",
"program": "Baseball"
},
{
"x": 1606798800000,
"y": 49.46,
"color": "#fc0303",
"program": "Baseball"
},
{
"x": 1577854800000,
"y": 34.8677,
"color": "#0bfc03",
"program": "Football"
},
{
"x": 1580533200000,
"y": 55.0675,
"color": "#fc0303",
"program": "Football"
},
{
"x": 1583038800000,
"y": 25.5852,
"color": "#0bfc03",
"program": "Football"
},
{
"x": 1585713600000,
"y": 98.1176,
"color": "#fc0303",
"program": "Football"
},
{
"x": 1588305600000,
"y": 91.8481,
"color": "#fc0303",
"program": "Football"
},
{
"x": 1590984000000,
"y": 62.554,
"color": "#fc0303",
"program": "Football"
},
{
"x": 1593576000000,
"y": 54.0914,
"color": "#fc0303",
"program": "Football"
},
{
"x": 1596254400000,
"y": 34.9944,
"color": "#0bfc03",
"program": "Football"
},
{
"x": 1598932800000,
"y": 13.6009,
"color": "#0bfc03",
"program": "Football"
},
{
"x": 1601524800000,
"y": 2.7292,
"color": "#0bfc03",
"program": "Football"
},
{
"x": 1604203200000,
"y": 55.5105,
"color": "#fc0303",
"program": "Football"
},
{
"x": 1606798800000,
"y": 64.9702,
"color": "#fc0303",
"program": "Football"
},
{
"x": 1577854800000,
"y": 25.0526,
"color": "#0bfc03",
"program": "All"
},
{
"x": 1580533200000,
"y": 79.5283,
"color": "#fc0303",
"program": "All"
},
{
"x": 1583038800000,
"y": 88.3788,
"color": "#fc0303",
"program": "All"
},
{
"x": 1585713600000,
"y": 72.801,
"color": "#fc0303",
"program": "All"
},
{
"x": 1588305600000,
"y": 29.0157,
"color": "#0bfc03",
"program": "All"
},
{
"x": 1590984000000,
"y": 78.9862,
"color": "#fc0303",
"program": "All"
},
{
"x": 1593576000000,
"y": 42.0415,
"color": "#0bfc03",
"program": "All"
},
{
"x": 1596254400000,
"y": 10.274,
"color": "#0bfc03",
"program": "All"
},
{
"x": 1598932800000,
"y": 7.1479,
"color": "#0bfc03",
"program": "All"
},
{
"x": 1601524800000,
"y": 24.364,
"color": "#0bfc03",
"program": "All"
},
{
"x": 1604203200000,
"y": 88.4601,
"color": "#fc0303",
"program": "All"
},
{
"x": 1606798800000,
"y": 46.5574,
"color": "#fc0303",
"program": "All"
}
]
};
const filterReleaseFrequency = (release_frequency_data = [], program) =>
release_frequency_data.filter(p => p.program.toLowerCase() === program.toLowerCase());
const filterReleaseFrequency = (release_frequency_data = [], program) =>
JSON.parse(JSON.stringify(release_frequency_data.filter(p => p.program.toLowerCase() === program.toLowerCase())));