反应-Redux组件无法在状态更改时重新呈现而不会改变状态

时间:2019-10-01 01:13:07

标签: reactjs redux react-redux redux-thunk react-thunk

问题:我正在使用带有Redux存储的React来管理状态。我想在组件上显示过滤器。这些过滤器将从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:使用连接功能,我将在组件属性中提取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。 这不允许我在屏幕上显示数组的内容。

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

感谢所有的帮助:)

2 个答案:

答案 0 :(得分:0)

正在进行很多工作,并且可能是与Tableau集成的一种更好的方法,但是为了解决您的问题,我认为您只需要将dispatch(fetchFilter(filterNames));移到{{ 1}}操作。

then()

答案 1 :(得分:0)

Mailbox 1 name1 name2 name3 Mailbox 2 name1 name2 name3 中,您可以尝试在'import UIKit class ViewController: UIViewController { var numberOnScreen: Double = 0; var previousNumber: Double = 0; var performingMath: false var operation = 0;' 函数的末尾移动fetchDashboard

dispatch(fetchFilter(filterNames));不是异步操作,这意味着您正在使用空数组调度onFirstInteractive(在这种情况下new window.tableau.Viz(vizContainer, url, options)无济于事,请参阅here)。