Проблема: я использую React с хранилищем Redux для управления своим состоянием. Я хочу отобразить фильтры на компоненте. Эти фильтры будут возвращены из API таблиц Javascript. На основании возврата из таблицы JavaScriptAPI я обновляю состояние в магазине. Состояние корректно обновляется с правильными фильтрами, что также вызывает обновление / повторную визуализацию моего компонента. Пока все хорошо.
Но когда я пытаюсь получить доступ к этим фильтрам (будь то объект с помощью Object.keys () или массив с помощью array.length) из state.props, я получаю нулевой массив в ответ.
Вероятно, это связано с неправильным использованием 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
);
}
Шаг 2А: Вот действие fetchDashboard: В рамках этого действия я создаю массив filterNAmes, который я хочу отобразить в моем компоненте. Я напеваю Thunk здесь, так как мои действия отправляют запрос API в Tableau JavascriptAPI. То, как я хочу, чтобы это работало, один раз, мы получаем ответ от API, мы отправляем viz редуктору и массив 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;
};
Это корректно обновляет состояние 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. Это не позволяет мне отображать содержимое массива на моем экране.
Это много для чтения, но я не могу его уместитьв меньшем описании. Пожалуйста, дайте мне знать, если мне нужно добавить больше деталей.
Заранее спасибо за помощь:)