React-Redux组件尽管在状态更改时重新呈现但未更改状态,但仍未正确显示array.length

问题描述 投票:0回答:1

问题:我正在将React与Redux存储结合使用来管理我的状态。我想在组件上显示过滤器。这些过滤器将从Tableau Javascript API返回。基于Tableau JavaScriptAPI的返回,我正在更新存储中的状态。状态已使用正确的过滤器正确更新,这也导致我的组件进行更新/重新渲染。到目前为止一切都很好。

但是当我尝试从state.props访问这些过滤器(使用Object.keys()作为对象或使用array.length的数组)时,我得到的是空数组。

这可能是由于错误地使用了Thunk / Async Await。

这里是代码段

[第1步:从React调用动作。单击按钮时,称为获取仪表板动作

class DashboardView extends Component {
  componentDidMount() {
    id = this.props.dashboardDetails.categoryID;
    console.log("Mounted");
    this.props.fetchDashboard(
      this.props.dashboardDetails.categoryURL,
      this.vizContainer
    );
  }

步骤2A:这是fetchDashboard动作:在此操作中,我正在创建要显示在组件上的filterNAmes数组。我在这里唱Thunk,因为我的动作向Tableau JavascriptAPI发送了API请求。我希望它的工作方式是一次,我们从API获得响应,将视力分配给reducer,将filterNames数组分配给另一个动作fetchFilter。附有摘要。

export const fetchDashboard = (url, vizContainer) => async dispatch => {
  let filterNames = [];
  //  let titlesTemp = {};
  //const vizContainer = {};
  const options = {
    hideToolbar: true,
    onFirstInteractive: function() {
      let workbook = viz.getWorkbook();
      const activeSheet = workbook.getActiveSheet();
      activeSheet
        .getWorksheets()
        .get("Index")
        .getFiltersAsync()
        .then(function(filters) {
          for (let filter in filters) {
            let filterTitle = filters[filter].getFieldName();
            let filterName = {};
            filterName[filterTitle] = [];
            let len = filters[filter].getAppliedValues().length;
            for (let i = 0; i < len; i++) {
              filterName[filterTitle].push(
                filters[filter].getAppliedValues()[i].value
              );
            }
            filterNames.push(filterName);
          }
        });
    }
  };
  let viz = await new window.tableau.Viz(vizContainer, url, options);
  dispatch({ type: "FETCH_DASHBOARD", payload: { viz } });
  console.log(filterNames, filterNames.length);
  return dispatch(fetchFilter(filterNames));
};

当我console.log(filterNames,filterNames.length)时,filterNames数组中包含元素(稍后将对其进行评估),但filterNames.length返回0。我认为这是问题的根本原因。我只想在填充FilterNames时分派下一个动作。

步骤2B:

export const fetchFilter = filterNames => {
  console.log("FETCH_FILTER action called", filterNames);
  return { type: "FETCH_FILTER", filterNames };
};

假设这不是问题,步骤3:减速器

const fetchFilterReducer = (fetchFilter = [], action) => {
  if (action.type === "FETCH_FILTER") {
    console.log("fetchfilterreducercalled:", action.filterNames);
    return action.filterNames;
  }
  return fetchFilter;
};

这将正确更新存储中的State fetchFilter。

第4步:使用connect函数,我在组件的属性中提取了fetchFilter数组。

class FilterDisplay extends React.Component {
  componentDidMount() {
    console.log(this.props);
    if (this.props.selectionFilters.length !== 0) {
      console.log(this.props);
    }
  }

  componentDidUpdate() {
    console.log(this.props.selectionFilters.length);
    if (this.props.selectionFilters.length !== 0) {
      console.log("filter display updated");
      console.log(this.props);     
    }
  }

  render() {
    return <div>hey</div>; //<Tile></Tile>;
  }
}

const mapStateToProps = state => {
  console.log("first  filters in state:", state.fetchFilter);

  return {
    selectionFilters: state.fetchFilter
  };
};
export default connect(mapStateToProps)(FilterDisplay);

在我的componentDidUpdate上,我将selectionFilters数组的长度设为0。这不允许我在屏幕上显示数组的内容。

这要读很多东西,但我无法在较小的描述中进行介绍。如果需要添加更多详细信息,请告诉我。

感谢您提前提供的所有帮助:]

reactjs redux react-redux redux-thunk react-thunk
1个回答
0
投票

[这里正在进行很多工作,可能是与Tableau集成的更好方法,但是为了解决您的问题,我认为您只需在dispatch(fetchFilter(filterNames));操作中将then()移到fetchDashboard块内。

.then(function(filters) {
  // all that other code ...
  dispatch(fetchFilter(filterNames));
});

0
投票

fetchDashboard中,您可以尝试在dispatch(fetchFilter(filterNames));功能的末尾移动onFirstInteractive

[new window.tableau.Viz(vizContainer, url, options)不是异步操作,这意味着您正在使用空数组调度fetchFilter(在这种情况下,console.log无效,请参阅here)。

© www.soinside.com 2019 - 2024. All rights reserved.