reactjs - 再次调用同一路线时,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.js
to回来时它会起作用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],
};
};
- sagas.js:
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()]);
}
- 减速器.js
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;
最后,这是
- favorites.js,其中
console.log('inFavs', favList);
返回空/空数组
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);
- 应用程序.js
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);
- index.js
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();
解决方案
推荐阅读
- django - 如何在页面url中注册id?
- firebase - 数组中项目的安全检查每次都返回 false
- java - Android Room“错误的 RuntimeInvisibleParameterAnnotations 属性”
- python - 即使在 __init__ 之后,Python Import 也会给出未找到的包
- shopware - 如何将商店软件与其他应用程序集成?
- spring-cloud-stream - 路由器作为 Spring Cloud 数据流中的处理器
- node.js - 尝试安装 Angular Cli 或更新当前 Node.js 版本时出错
- swift - Scrollview 在键盘出现时创建插图,但不会自动向上移动到 textview
- android - Xamarin 在刷新顶部显示空单元格的列表后形成没有缓存策略的列表视图
- java - 如何在 Spring Security xml 中设置响应标头?