Javascript 在一个组件中更新redux存储不会反映在另一个组件中
我有一个过滤器组件:Javascript 在一个组件中更新redux存储不会反映在另一个组件中,javascript,reactjs,redux,state,Javascript,Reactjs,Redux,State,我有一个过滤器组件: import React from 'react'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import { Dropdown } from 'semantic-ui-react'; import { changeYear } from '../../actions/menuFiltersActions'; import makeDropdownOptions
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { Dropdown } from 'semantic-ui-react';
import {
changeYear
} from '../../actions/menuFiltersActions';
import makeDropdownOptions from '../../lib/makeDropdownOptions';
export class YearFilter extends React.Component {
constructor(props) {
super(props);
this.handleChangeYear = this.handleChangeYear.bind(this)
}
handleChangeYear(year) {
console.log(year)
this.props.changeYear(year)
this.props.getClientActuals()
// this.props.testSelectedYear()
console.log(this.props.years.selectedYear)
}
render() {
return (
<div id="YearFilter">
<span>Year</span>
<Dropdown
// fluid
selection
loading={!this.props.years.data.length}
options={makeDropdownOptions(this.props.years.data)}
value={this.props.years.selectedYear}
onChange={(e, { value }) => this.handleChangeYear(value)}
/>
</div>
);
}
}
YearFilter.propTypes = {
years: PropTypes.exact({
data: PropTypes.array,
selectedYear: PropTypes.number
}).isRequired,
changeYear: PropTypes.func.isRequired,
getClientActuals: PropTypes.func.isRequired,
};
export default connect(
store => ({
years: store.menuFilters.years
}),
{
changeYear
}
)(YearFilter);
从“React”导入React;
从'react redux'导入{connect};
从“道具类型”导入道具类型;
从“语义ui反应”导入{Dropdown};
进口{
变更年
}来自“../actions/menuFiltersActions”;
从“../../lib/makeDropdownOptions”导入makeDropdownOptions;
导出类YearFilter扩展React.Component{
建造师(道具){
超级(道具);
this.handleChangeYear=this.handleChangeYear.bind(this)
}
handleChangeYear(年){
控制台日志(年)
此.props.changeyar(年)
this.props.getClientActuals()
//this.props.testSelectedYear()
console.log(this.props.years.selectedYear)
}
render(){
返回(
年
此.handleChangeYear(值)}
/>
);
}
}
YearFilter.propTypes={
年份:精确({
数据:PropTypes.array,
selectedYear:PropTypes.number
}).要求,
变更年:需要PropTypes.func.isRequired,
getClientActuals:PropTypes.func.isRequired,
};
导出默认连接(
商店=>({
年份:store.menuFilters.years
}),
{
变更年
}
)(年度过滤器);
每当用户从下拉列表中选择年份时,我都会使用它来更新Redux应用商店中的menuFilters.years.selectedYear属性
父组件如下所示:
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { Header, Button, Icon, Loader} from 'semantic-ui-react';
import {
changeYear
} from '../../actions/menuFiltersActions';
import {
saveSalesHouseForecastSpendData
} from '../../actions/forecastSpendDataActions';
import './TabDataEntry.css';
import DataEntryFiltersSidebar from '../DataEntryFiltersSidebar/DataEntryFiltersSidebar';
import YearFilter from '../YearFilter/YearFilter';
import PivotTable from '../PivotTable/PivotTable';
import PivotTableAPI from '../../api/PivotTableAPI';
import processForecastSpendData from '../../lib/processForecastSpendData';
import { SALESHOUSE_LEVEL, MONTHS } from '../../constants';
export class TabDataEntry extends React.Component {
constructor(props) {
super(props);
this.state = {
isSavingChanges: false,
showNotification: false,
showPivotTable: false
}
this.getClientActuals = this.getClientActuals.bind(this);
this.getClientActualsFilters = this.getClientActualsFilters.bind(this);
this.saveForecasts = this.saveForecasts.bind(this);
this.collectChangedForecasts = this.collectChangedForecasts.bind(this);
this.testSelectedYear = this.testSelectedYear.bind(this);
}
componentDidUpdate(prevProps) {
if (prevProps.menuFilters.years.data !== this.props.menuFilters.years.data){
this.props.changeYear(this.props.menuFilters.years.data[0]);
}
}
getClientActualsFilters(extraParams) {
const filters = {
year: this.props.menuFilters.years.selectedYear,
client_id: this.props.menuFilters.brands.selectedBrand,
...extraParams
};
// console.log(filters)
if (this.props.menuFilters.media.selectedMedia) {
filters.media_id = this.props.menuFilters.media.selectedMedia;
}
if (this.props.menuFilters.media.selectedBooking) {
filters.booking_id = this.props.menuFilters.media.selectedBooking;
}
return filters;
}
testSelectedYear(){
console.log(this.props.menuFilters.years.selectedYear)
}
async getClientActuals() {
try {
const clientActuals = await PivotTableAPI.getClientActuals(this.getClientActualsFilters());
this.props.saveSalesHouseForecastSpendData(
processForecastSpendData(clientActuals, { level: SALESHOUSE_LEVEL })
);
this.setState({showPivotTable: true})
} catch (e) {console.log(e)}
}
async saveForecasts() {
this.setState({ isSavingChanges: true })
let forecast = this.collectChangedForecasts(this.props.forecastSpendData);
try {
const response = await PivotTableAPI.saveForecasts({
media_id: this.props.menuFilters.media.selectedMedia,
booking_id: this.props.menuFilters.media.selectedBooking,
advertiser_id: this.props.menuFilters.brands.selectedBrand,
year: this.props.menuFilters.years.selectedYear,
forecast_period: [],
forecast
});
this.notify(response ? 'positive' : 'negative');
} catch (e) { console.log(e) }
this.setState({ isSavingChanges: false })
}
collectChangedForecasts(data) {
const childrenKeys = {
Saleshouse: 'folios',
Folio: 'suppliers'
};
let changedForecasts = Object.values(data).reduce((changedForecasts, saleshouse) => {
for (let month in MONTHS) {
// check if forecast has changed and if this element is the level at which data was entered
if (saleshouse[MONTHS[month]]
&& saleshouse[MONTHS[month]].changed
&& saleshouse[MONTHS[month]].forecastLevel === saleshouse.level) {
changedForecasts.push({
month: parseInt(month) + 1,
sales_house_id: saleshouse.SaleshouseId,
folio_id: saleshouse.FolioId,
supplier_id: saleshouse.SupplierId,
forecast_level: saleshouse[MONTHS[month]].forecastLevel,
metric: saleshouse[MONTHS[month]].forecast
});
}
}
let children = saleshouse[ childrenKeys[saleshouse.level] ]
if (children && Object.values(children).length) {
changedForecasts.push(...this.collectChangedForecasts(children))
}
return changedForecasts;
}, [])
return changedForecasts
}
notify(state) {
this.setState({ showNotification: state })
setTimeout(() => this.setState({ showNotification: false }), 5000)
}
render() {
return (
<div id="TabDataEntry">
<DataEntryFiltersSidebar
getClientActuals={this.getClientActuals}
/>
<div id="main-container">
<div className="header-section">
<Header as="h2">Investment forecasts</Header>
<p>
Select a Client / Advertiser to view and confirm the current share deal spends.
<Loader as="span" active={this.state.isSavingChanges} inline size="mini" inverted />
{ this.state.showNotification &&
<span className={`notification ${this.state.showNotification}`}><Icon name="checkmark"/>Saved</span>
}
</p>
</div>
{this.state.showPivotTable &&
<>
<YearFilter
getClientActuals={this.getClientActuals}
testSelectedYear={this.testSelectedYear}
/>
<div id="overflowing-container">
<PivotTable
getClientActualsFilters={this.getClientActualsFilters}
/>
<div id="bottom-buttons">
<div>
<Button
primary
onClick={this.saveForecasts}
disabled={!Object.keys(this.props.forecastSpendData).length}
>
<Loader active={this.state.isSavingChanges} inline size="mini" inverted /> Save Changes
</Button>
<Button
basic
onClick={this.getClientActuals}
disabled={!Object.keys(this.props.forecastSpendData).length}
>
Cancel
</Button>
</div>
<Button basic disabled><Icon name='balance scale'/>Rebalance Calculator</Button>
<Button basic disabled><Icon name='file excel outline'/>Export as XLS</Button>
</div>
</div>
</>
}
</div>
</div>
);
}
}
TabDataEntry.propTypes = {
menuFilters: PropTypes.objectOf(PropTypes.object).isRequired,
forecastSpendData: PropTypes.objectOf(PropTypes.object).isRequired,
saveSalesHouseForecastSpendData: PropTypes.func.isRequired,
changeYear: PropTypes.func.isRequired
};
export default connect(
store => ({
menuFilters: store.menuFilters,
forecastSpendData: store.forecastSpendData
}),
{ saveSalesHouseForecastSpendData, changeYear }
)(TabDataEntry);
从“React”导入React;
从'react redux'导入{connect};
从“道具类型”导入道具类型;
从“语义ui反应”导入{标题、按钮、图标、加载程序};
进口{
变更年
}来自“../actions/menuFiltersActions”;
进口{
saveSalesHouseForecastSpendData
}来自“../actions/forecastSpendDataActions”;
导入“/TabDataEntry.css”;
从“../DataEntryFiltersSidebar/DataEntryFiltersSidebar”导入DataEntryFiltersSidebar;
从“../YearFilter/YearFilter”导入YearFilter;
从“../PivotTable/PivotTable”导入数据透视表;
从“../../api/PivotTableAPI”导入数据透视表api;
从“../../lib/processForecastSpendData”导入processForecastSpendData;
从“../../constants”导入{SALESHOUSE_LEVEL,MONTHS};
导出类TabDataEntry扩展React.Component{
建造师(道具){
超级(道具);
此.state={
isSavingChanges:错误,
showNotification:false,
显示数据透视表:false
}
this.getClientActuals=this.getClientActuals.bind(this);
this.getClientActualFilters=this.getClientActualFilters.bind(this);
this.saveForecasts=this.saveForecasts.bind(this);
this.collectChangedForecasts=this.collectChangedForecasts.bind(this);
this.testSelectedYear=this.testSelectedYear.bind(this);
}
componentDidUpdate(prevProps){
if(prevProps.menuFilters.years.data!==this.props.menuFilters.years.data){
this.props.changeYear(this.props.menuFilters.years.data[0]);
}
}
GetClientActualFilters(extraParams){
常数过滤器={
年份:this.props.menuFilters.years.selectedYear,
客户id:this.props.menuFilters.brands.selectedBrand,
…额外参数
};
//console.log(过滤器)
if(this.props.menuFilters.media.selectedMedia){
filters.media\u id=this.props.menuFilters.media.selectedMedia;
}
if(this.props.menuFilters.media.selectedBooking){
filters.booking_id=this.props.menuFilters.media.selectedBooking;
}
回流过滤器;
}
testSelectedYear(){
console.log(this.props.menuFilters.years.selectedYear)
}
异步getClientActuals(){
试一试{
const clientActuals=await PivotTableAPI.getClientActuals(this.GetClientActualFilters());
this.props.saveSalesHouseForecastSpendData(
processForecastSpendData(客户端,{level:SALESHOUSE_level})
);
this.setState({showPivotTable:true})
}catch(e){console.log(e)}
}
异步存储预测(){
this.setState({isSavingChanges:true})
让forecast=this.collectChangedForecast(this.props.forecastSpendData);
试一试{
const response=wait PivotTableAPI.saveforecast({
媒体id:this.props.menuFilters.media.selectedMedia,
预订id:this.props.menuFilters.media.selectedBooking,
广告商id:this.props.menuFilters.brands.selectedBrand,
年份:this.props.menuFilters.years.selectedYear,
预测期:[],
预测
});
通知(响应?'positive':'negative');
}catch(e){console.log(e)}
this.setState({isSavingChanges:false})
}
CollectChangedForecast(数据){
常量childrenKeys={
售楼处:'对开本',
对开本:“供应商”
};
让changedForecasts=Object.values(data).reduce((changedForecasts,saleshouse)=>{
用于(以月为单位){
//检查预测是否已更改,以及此元素是否为输入数据的级别
if(销售部[月[月])
&&saleshouse[月[月]。已更改
&&saleshouse[月[月]].forecastLevel==saleshouse.level){
changedforecast.push({
月份:parseInt(月)+1,
sales\u house\u id:saleshouse.saleshouse id,
对开本id:saleshouse.FolioId,
供应商id:saleshouse.SupplierId,
预测级别:saleshouse[月].预测级别,
指标:saleshouse[月].预测
});
}
}
let children=saleshouse[childrenKeys[saleshouse.level]]
if(children&&Object.values(children.length){
ChangedForecast.push(…此.CollectChangedForecast(子项))
}
返回已更改的预测;
}, [])
返回更改预测
}
通知(州){
this.setState({showNotification:state})
setTimeout(()=>this.setState({showNotification:false}),5000)
}
render(){
返回(
投资预测
选择客户/广告客户以查看和确认当前
this.props.changeYear(year)
<YearFilter
getClientActuals={this.getClientActuals}
testSelectedYear={this.testSelectedYear}
/>
changeYear(year);
if (this.props.years.selectedYear !== prevProps.years.selectedYear) {
this.props.getClientActuals()
}