问题:我正在使用带有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。 这不允许我在屏幕上显示数组的内容。
要阅读的内容很多,但我无法在较小的描述中进行介绍。 如果需要添加更多详细信息,请告诉我。
感谢所有的帮助:)
答案 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)。