首页 > 解决方案 > 再次调用同一路线时,mapStateToProps 未调用

问题描述

首先,我"react": "^16.13.0",只使用功能组件,而不是类,以及

"react-redux": "^7.2.0", "react-router": "^5.2.0", "redux": "^4.0.5", "redux-saga": "^1.1.3", "webpack": "^4.42.0",

我在 react 组件中有 2 个组件 -landingPage.js它从 localStorage 获取最喜欢的值,并在初始渲染时将其存储到 redux-store。当我导航到收藏夹组件时,它调用mapDispatchToProps,从 store -> 选择器中获取favsList值并呈现列表。

当我尝试在收藏夹中点击收藏夹(相同组件)按钮时,mapStateToProps没有被调用,因此没有渲染favsList. 虽然我仍然看到 redux 商店中的状态完好无损,但没有改变。

> 问题1: 如果状态没有改变(这里如果favsList 没有更新)mapStateToProps 不会被调用?landingPage.js如果是,为什么当我从tofavorites.js而不是 from favorites.jsto回来时它会起作用favorites.js

> 问题 2:mapStateToProps在初始组件渲染时触发的替代方法是什么?

编辑添加代码片段:

这是登陆页面:

import React, { useEffect } from 'react';

import { connect } from 'react-redux';
import { fetchItemDetailsRequest, saveItemToFavSuccess } from '../Services/actions';
import { lastCatRouteSelector, favListSelector } from '../Services/selectors';
import Home from '../Components/Common/home';

function Home({
    itemData,
    dispatchItemData,
    handleSwitch,
    selectedLanguage,
    dispatchSetInitialFavList,
}) {


    useEffect(() => {
        dispatchSetInitialFavList();
    }, []);

    return (
        <div className={coreStyles.mainContent}>
            <Home />
        </div>
    );
}
const mapStateToProps = (state) => ({
    itemData: lastCatRouteSelector(state),
});

const mapDispatchToProps = (dispatch) => ({
    dispatchItemData: () => {
        dispatch(fetchItemListRequest());
    },
    dispatchSetInitialFavList: () => {
        dispatch(saveItemToFavSuccess());
    },
});


export default connect(mapStateToProps, mapDispatchToProps)(DLJHome);

在上面你我想让你看到

dispatchSetInitialFavList: () => {
            dispatch(saveItemToFavSuccess());
        },

它将 favList 保存到存储。对应的actions.js

export const saveItemToFavSuccess = (itemId, fetchedItems) => {
        let favList = !localStorage.getItem('favList')
            ? []
            : JSON.parse(localStorage.getItem('favList')).length > 1
            ? JSON.parse(localStorage.getItem('favList'))
            : [JSON.parse(localStorage.getItem('favList'))[0]];

        itemId ? favList.push(itemId.toString()) : null;

        localStorage.setItem('favList', JSON.stringify(favList));
        return {
            type: SAVE_ITEM_TO_FAV_SUCCESS,
            payload: fetchedItems ? [favList, fetchedItems] : [favList],
        };
    };

function* saveItemToFav() {
    yield takeEvery(SAVE_ITEM_TO_FAV_REQUEST, saveItemToFavRequest);
}

function* saveItemToFavRequest(action) {
    try {
        const itemId = action.payload;
        const existingFavs = yield select(favListSelector);
        yield put(saveItemToFavSuccess([itemId]));
    } catch (saveFavError) {
        console.warn('Error occured while saving to fav', saveFavError);
    }
}

export default function* rootSaga() {
    yield all([fetchItemDetails(), saveCatRoute(), saveItemToFav(), saveItemRoute()]);
}

function saveItemToFavReduer(state = null, action) {
    switch (action.type) {
        case SAVE_ITEM_TO_FAV_SUCCESS:
            return { favList: deducePayload(action) };
        default:
            return state;
    }
}

const itemCategoryReducer = combineReducers({
    favList: saveItemToFavReduer,
});
const deducePayload = (action) => {
    return action.payload;
};
export default itemCategoryReducer;

最后,这是

import { connect } from 'react-redux';
import { itemDetailsSelector, favListSelector } from '../../Services/selectors';
import { saveItemToFavReduer } from '../../Services/reducers';

function Favorites({ favList, itemDetails, dispatchFetchItemData }) {
    console.log('inFavs', favList);
);
}
const mapStateToProps = (state) => ({
    favList: state.favList,
    itemDetails: state.itemDetails ? state.itemDetails : [],
});

const mapDispatchToProps = (dispatch) => ({
    dispatchFetchItemData: (itemId) => {
        dispatch(fetchItemDetailsRequest(itemId));
    },
});

export default connect(mapStateToProps, mapDispatchToProps)(Favorites);

import React, { useState } from 'react';
import { IntlProvider, FormattedMessage } from 'react-intl';
import messages from './Core/i18n';
import { HashRouter, Route, Switch, withRouter } from 'react-router-dom';
import Home from './Components';
import Favorites from './Components/Common/favorites';

function App() {
const [locale, setLocale] = useState(
        localStorage.getItem('localValue') ? localStorage.getItem('localValue') : 'en',
    );
    const handleSwitch = (language) => {
        setLocale(language);
        localStorage.setItem('localValue', language);
    };
    return (
        <IntlProvider locale={locale} messages={messages[locale]}>
            <Switch>
                <Route
                    exact={true}
                    path="/"
                    component={() => <Home handleSwitch={handleSwitch} selectedLanguage={locale} />}
                />
                <Route
                    exact={true}
                    path="/home"
                    component={() => <Home handleSwitch={handleSwitch} selectedLanguage={locale} />}
                />
                <Route path="/categories/" component={ItemCategory} />
                <Route path="/favorites/" component={Favorites} />
            </Switch>
        </IntlProvider>
    );
}

export default withRouter(App);

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import 'regenerator-runtime/runtime';
import 'core-js/stable';
import { HashRouter, Route, Switch, withRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './Services/store';

const title = 'Title';

ReactDOM.render(
    <Provider store={store}>
        <HashRouter>
            <App title={title} />
        </HashRouter>
    </Provider>,
    document.getElementById('app'),
);

module.hot.accept();

标签: reactjsreact-reduxreact-routerredux-sagamapstatetoprops

解决方案


推荐阅读