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()
}