Почему атрибуты начального состояния устанавливаются как неопределенные во время начального рендеринга?

#reactjs #redux

#reactjs #сокращение

Вопрос:

Вот код действия, редуктора и компонента. Состояние из mapstatetoprops правильное, но после этого я не понимаю, в чем проблема, и все атрибуты начального состояния не определены. Я также использую combinedreducer, я не знаю, оказывает ли это какое-либо влияние

Вот файлы компонентов, редукторов и действий:

 import React from "react";
import { connect } from "react-redux";
import {
  changeOnClick,
  fetchData,
  setData,
  changeOnConfig,
} from "./redux/CategoryAction";

class AllCatLevelKeywordsMapping extends React.Component {

  componentDidMount() {
    const data = this.props.fetchData(1);
    this.props.setData(data);
  }

  render() {
    const { loading, currentPageNo, errorMessage, totalPages } = this.props;
    const showPrevLink = 1 < currentPageNo;
    const showNextLink = totalPages > currentPageNo;

    return (
      <div className="container">
        <h1>All Category Level Keyword Mapping Rules</h1>
        
        
      </div>
    );
  }
}
const mapStateToProps = (state) => {
  return {
    loading: state.loading,
    results: state.results,
    totalResults: state.totalResults,
    totalPages: state.totalPages,
    currentPageNo: state.currentPageNo,
    errorMessage: state.errorMessage,
    selectedCountry: state.selectedCountry,
    isCountryDisabled: state.isCountryDisabled,
    selectedPlatform: state.selectedPlatform,
    isPlatformDisabled: state.isPlatformDisabled,
    selectedLanguage: state.selectedLanguage,
    isLanguageDisabled: state.isLanguageDisabled,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    setData: (data) => dispatch(setData(data)),
    changeOnClick: () => dispatch(changeOnClick()),
    changeOnConfig: (config) => dispatch(changeOnConfig(config)),
    fetchData: (data) => dispatch(fetchData(data)),
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(AllCatLevelKeywordsMapping);
 
 //action file
 
 import axios from "axios";

export const setData = (payload) => ({
  type: "SET_DATA",
  payload,
});

export const changeOnClick = () => ({
  type: "CHANGE_ON_CLICK",
});

export const changeOnConfig = (payload) => ({
  type: "CHANGE_ON_CONFIG",
  payload,
});

export const fetchData = (updatedPageNo = "", country = "uae") => {
  return (dispatch) => {
    const getPageCount = (total, denominator) => {
      const divisible = 0 === total % denominator;
      const valueToBeAdded = divisible ? 0 : 1;
      return Math.floor(total / denominator)   valueToBeAdded;
    };
    const pageNumber = updatedPageNo ? `${updatedPageNo}` : 1;
    const searchBody = {
      top: 5,
      skip: pageNumber * 5 - 5,
      country: country,
    };
    if (cancel) {
      cancel.cancel();
    }
    const cancel = axios.CancelToken.source();

    let data = [];
    axios({
      method: "post",
      url: "/cat-level-get-keyword",
      data: searchBody,
    })
      .then((res) => {
        const resultNotFoundMsg = !res.data.records.length
          ? "No results found."
          : "";
        res.data.records.forEach((element) => {
          data.push({
            id: element.id,
            label: element.label,
            catLevel1: element.catLevel1,
            catLevel2: element.catLevel2,
            catLevel3: element.catLevel3,
            catLevel4: element.catLevel4,
            search_terms: element.search_terms,
          });
        });
        const total = res.data.totalRecords;
        const totalPagesCount = getPageCount(total, 5);
        dispatch({
          type: "FETCH_DATA",
          payload: {
            results: data,
            totalPages: totalPagesCount,
            currentPageNo: updatedPageNo,
            errorMessage: resultNotFoundMsg,
          },
        });
      })
      .catch((error) => {
        if (axios.isCancel(error) || error) {
          dispatch({
            type: "SET_ERROR",
            payload: {
              error:
                "Failed to fetch the data. Please check network connection ",
            },
          });
        }
      });
  };
};
 
 //reducer :
 
 const initialState = {
  loading: true,
  results: [],
  totalResults: 0,
  totalPages: 0,
  currentPageNo: 0,
  errorMessage: "",
  selectedCountry: "",
  isCountryDisabled: false,
  selectedPlatform: "",
  isPlatformDisabled: false,
  selectedLanguage: "",
  isLanguageDisabled: false,
};

console.log("state from reducer is : ", initialState);

const mapCategeoryReducer = (state = initialState, action) => {
  switch (action.type) {
    case "SET_DATA":
      return {
        ...state,
        results: action.payload,
      };

    case "CHANGE_ON_CLICK":
      return {
        ...state,
        loading: true,
        errorMessage: "",
      };

    case "CHANGE_ON_CONFIG":
      return {
        ...state,
        selectedCountry: action.payload.country,
        selectedPlatform: action.payload.platform,
        selectedLanguage: action.payload.language,
      };

    case "FETCH_DATA":
      return {
        ...state,
        loading: false,
        ...action.payload,
      };

    case "SET_ERROR":
      return {
        ...state,
        loading: false,
        errorMessage: action.payload.error,
      };

    default:
      return state;
  }
};

export default mapCategeoryReducer;
 

Комментарии:

1. Что говорят инструменты redux devtools? Регистрировали ли вы состояние в своих mapStateToProps?

Ответ №1:

Похоже, вам не хватает имени состояния в rootreducer,

например, если в корневом редукторе это похоже:

const reducer = combineReducers({ mapCategeory: mapCategeoryReducer, });

затем вам нужно использовать в mapstatetoprops что-то вроде этого:

загрузка: state.mapCategeory.loading,

и то же самое для всех остальных атрибутов