Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

reactjs - Warning: Using UNSAFE_componentWillMount in strict mode is not recommended (upgrade to CRA 4.0.2)

I updated my react app from 16.3+ to react 17 while upgrading to [email protected] and everything works as expected, but I see in the console the following:

Warning: Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See react-unsafe-component-lifecycles for details.

* Move code with side effects to componentDidMount, and set initial state in the constructor.

Please update the following components: SideEffect(NullComponent)

My App.jsx file:

import React, { useRef, useEffect, useCallback, createRef } from 'react';
import { useDispatch, useSelector, batch } from 'react-redux';
import './App.scss';
import { CountryBox, Error, MasterBox, MetaTags, ModalContainer, ScreenLoader } from '../../components';
import { dataActions, settingsActions, statisticsActions, statisticsUpdatesActions } from '../../store/actions/actions';
import { engineService } from '../../services';
import { coreUtils } from '../../utils';

const App = (props) => {
  const dispatch = useDispatch();
  // Refs.
  const elRefs = useRef([]);
  // State variables.
  const settingsList = useSelector((state) => state.settings.settingsList);
  const loadingList = useSelector((state) => state.settings.loadingList);
  const sourcesList = useSelector((state) => state.data.sourcesList);
  const countriesList = useSelector((state) => state.data.countriesList);
  const { isActive, isRefreshMode, viewType, isDisplayError, activeModalName,
    activeModalValue, isReplaceModalMode, isActionLoader } = settingsList;
  const { loadingPrecentage, isScreenLoaderComplete } = loadingList;
  // Functions to update the state.
  const onSetStateCurrentTime = (data) => dispatch(statisticsActions.setStateCurrentTime(data));
  const onSetStateSettingsList = (listName, listValues) => dispatch(settingsActions.setStateSettingsList(listName, listValues));
  const onSetStateStatisticsField = (fieldName, fieldValue) => dispatch(statisticsActions.setStateStatisticsField(fieldName, fieldValue));
  const onSetStateStatisticsList = (statisticsList) => dispatch(statisticsActions.setStateStatisticsList(statisticsList));
  const onSetStateStatisticsUpdatesSettingsList = (statisticsUpdatesSettingsList) => dispatch(statisticsUpdatesActions.setStateStatisticsUpdatesSettingsList(statisticsUpdatesSettingsList));
  const onSetStateDataCollection = (collectionName, collectionValue) => dispatch(dataActions.setStateDataCollection(collectionName, collectionValue));
  const onSetStateInitiateSettings = (data) => {
    const { settingsList, loadingList } = data;
    batch(() => {
      dispatch(settingsActions.setStateSettingsList('settingsList', settingsList));
      dispatch(settingsActions.setStateSettingsList('loadingList', loadingList));
    });
  };
  const onSetStateInitiateSources = (data) => {
    const { sourcesList, countriesList, countriesNameIdList, statisticsList, settingsList } = data;
    batch(() => {
      dispatch(dataActions.setStateDataCollection('sourcesList', sourcesList));
      dispatch(dataActions.setStateDataCollection('countriesList', countriesList));
      dispatch(dataActions.setStateDataCollection('countriesNameIdList', countriesNameIdList));
      dispatch(settingsActions.setStateSettingsList('settingsList', settingsList));
      dispatch(statisticsActions.setStateStatisticsList(statisticsList));
    });
  };
  const onSetStateUpdateRound = (data) => {
    const { countriesList, statisticsList, updateStatisticsUpdatesListResults } = data;
    const { statisticsUpdatesList, statisticsUpdatesSettingsList } = updateStatisticsUpdatesListResults;
    batch(() => {
      dispatch(dataActions.setStateDataCollection('countriesList', countriesList));
      dispatch(statisticsActions.setStateStatisticsList(statisticsList));
      if (statisticsUpdatesList && statisticsUpdatesList.length > 0) {
        dispatch(statisticsUpdatesActions.setStateStatisticsUpdatesList(statisticsUpdatesList));
        dispatch(statisticsUpdatesActions.setStateStatisticsUpdatesSettingsList(statisticsUpdatesSettingsList));
      }
    });
  };
  const onSetStateActionUpdate = (data) => {
    const { countriesList, settingsList } = data;
    batch(() => {
      dispatch(dataActions.setStateDataCollection('countriesList', countriesList));
      dispatch(settingsActions.setStateSettingsList('settingsList', settingsList));
    });
  };
  const onSetStateActionRefresh = (data) => {
    const { countriesList, settingsList, statisticsList, updateStatisticsUpdatesListResults } = data;
    const { statisticsUpdatesList, statisticsUpdatesSettingsList } = updateStatisticsUpdatesListResults;
    batch(() => {
      dispatch(dataActions.setStateDataCollection('countriesList', countriesList));
      dispatch(settingsActions.setStateSettingsList('settingsList', settingsList));
      dispatch(statisticsActions.setStateStatisticsList(statisticsList));
      if (statisticsUpdatesList && statisticsUpdatesList.length > 0) {
        dispatch(statisticsUpdatesActions.setStateStatisticsUpdatesList(statisticsUpdatesList));
        dispatch(statisticsUpdatesActions.setStateStatisticsUpdatesSettingsList(statisticsUpdatesSettingsList));
      }
    });
  };
  const onSetStateUpdateCountryVisibility = (data) => {
    const { countriesList, countriesNameIdList, statisticsList, statisticsUpdatesList } = data;
    batch(() => {
      dispatch(dataActions.setStateDataCollection('countriesList', countriesList));
      dispatch(dataActions.setStateDataCollection('countriesNameIdList', countriesNameIdList));
      dispatch(statisticsActions.setStateStatisticsList(statisticsList));
      if (statisticsUpdatesList && statisticsUpdatesList.length > 0) {
        dispatch(statisticsUpdatesActions.setStateStatisticsUpdatesList(statisticsUpdatesList));
      }
    });
  };

  // Run the engine.
  useEffect(() => {
    engineService.runEngine({
      mode: props.mode,
      onSetStateCurrentTime: onSetStateCurrentTime,
      onSetStateSettingsList: onSetStateSettingsList,
      onSetStateStatisticsField: onSetStateStatisticsField,
      onSetStateStatisticsList: onSetStateStatisticsList,
      onSetStateStatisticsUpdatesSettingsList: onSetStateStatisticsUpdatesSettingsList,
      onSetStateInitiateSettings: onSetStateInitiateSettings,
      onSetStateInitiateSources: onSetStateInitiateSources,
      onSetStateUpdateRound: onSetStateUpdateRound,
      onSetStateDataCollection: onSetStateDataCollection,
      onSetStateActionUpdate: onSetStateActionUpdate,
      onSetStateActionRefresh: onSetStateActionRefresh,
      onSetStateUpdateCountryVisibility: onSetStateUpdateCountryVisibility
    });
    return () => {
      engineService.clearSources();
    };
  }, []);

  // Set loader for each master action.
  useEffect(() => {
    engineService.updateActionLoader(false);
  }, [countriesList]);

  // After exit from any modal - Scroll back to the element's vertical position.
  const scrollToCountry = useCallback((data) => {
    const { action, value } = data;
    if (action === 'modal' && !value && activeModalValue && !isReplaceModalMode && activeModalName !== 'country') {
      setTimeout(() => {
        const offsetTop = elRefs.current.find(c => c.current?.dataset?.countryId === activeModalValue).current.offsetTop;
        if (offsetTop > window.innerHeight) {
          window.scrollTo(0, offsetTop);
        }
      }, 10);
    }
  }, [elRefs, activeModalValue, isReplaceModalMode]);

  // Update action on master modal click.
  const handleActionClick = useCallback((e) => {
    if (!isActionLoader) {
      const data = {
        action: coreUtils.getAttributeName(e, 'data-action'),
        value: coreUtils.getAttributeName(e, 'name'),
        id: coreUtils.getAttributeName(e, 'data-country-id')
      };
      scrollToCountry(data);
      engineService.runMasterActionClick(data);
    }
  }, [elRefs, activeModalValue, isReplaceModalMode]);

  // Update action on relevant modal change.
  const handleModalActionChange = useCallback((e) => {
    engineService.runModalActionUpdate({
      modalName: coreUtils.getAttributeName(e, 'data-modal-name'),
      action: coreUtils.getAttributeName(e, 'data-action'),
      value: coreUtils.getValue(e)
    });
  }, []);

  // Validate all OK to show the data and generate the countries.
  const isInitiateComplete = !isDisplayError && countriesList && countriesList.length > 0 && loadingPrecentage === 100;
  const renderCountries = useCallback(() => {
    const countriesDOM = [];
    const refsList = [];
    for (let i = 0; i < countriesList.length; i++) {
      const country = countriesList[i];
      const ref = elRefs.current[i] || createRef();
      refsList.push(ref);
      countriesDOM.push(
        (<CountryBox
          key={country.id}
          {...country} // React memo works only with seperated properties.
          isRefreshMode={isRefreshMode}
          sourcesList={sourcesList}
          onActionClick={handleActionClick}
          ref={ref}
        />));
    }
    elRefs.current = refsList;
    return countriesDOM;
  }, [countriesList]);

  return (
    <div className="main">
      {MetaTags}
      {!isScreenLoaderComplete &&
        <ScreenLoader
          isActive={isActive}
          loadingList={loadingList}
          isDisplayError={isDisplayError}
        />
      }
      {isDisplayError &&
        <Error
          isDisplayError={isDisplayError}
        />
      }
      {activeModalName &&
        <ModalContainer
          onActionClick={handleActionClick}
          onActionChange={handleModalActionChange}
        />
      }
      {isInitiateComplete &&
        <div className="page">
          <div className="main-container">
            <div className={`container ${viewType} f32 f32-extra locations`}>
              <MasterBox
                onActionClick={handleActionClick}
              />
              {renderCountries()}
            </div>
          </div>
        </div>
      }
    </div>
  );
};

export default App;

Does anyone faced this issue before? thanks.

question from:https://stackoverflow.com/questions/66045965/warning-using-unsafe-componentwillmount-in-strict-mode-is-not-recommended-upgr

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

OK I solved it. The issue was with one of the components named MetaTags:

MetaTags.jsx

import React from 'react';
import { Helmet } from 'react-helmet';
import { timeUtils } from '../../../utils';

const MetaTags =
    (<Helmet>
        <title data-rh="true">World Covid 19 Data | Covid 19 World Data | {timeUtils.getTitleDate()}</title>
    </Helmet>);

export default MetaTags;

The react-helmet package is outdated, and I needed to install 'react-helmet-async' instead, and change the code to:

initiate.jsx

app = (
    <HelmetProvider>
        <Suspense fallback={null}>
            <Provider store={createStore(rootReducer, composeEnhancers(applyMiddleware(thunk)))}>
                <Helmet>
                    <title data-rh="true">Dynamic title {timeUtils.getTitleDate()}</title>
                </Helmet>
                <BrowserRouter>
                    {component}
                </BrowserRouter>
            </Provider>
        </Suspense>
    </HelmetProvider>
);

This solved my issue and the warnning was gone.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...