![](/img/trans.png)
[英]Testing in React/Redux - how to guarantee that state has been updated?
[英]React component not refreshing when redux state has been updated with successful action
React / Redux組合的新功能,試圖解決問題。
用戶首次訪問或登錄時,會發出fetch_user api請求。 目的是使頁面根據其登錄狀態顯示不同。 在redux開發工具中,我可以看到狀態已更新,並且在初始狀態后將字段填充為“ auth”,但是,當我位於應用程序的子組件中時,該值被視為未定義。 如果您需要更多信息,請告訴我。 提前致謝。
// app.js
const initialState = {};
const history = createHistory();
const store = configureStore(initialState, history);
const MOUNT_NODE = document.getElementById('app');
const render = messages => {
ReactDOM.render(
<Provider store={store}>
<LanguageProvider messages={messages}>
<ConnectedRouter history={history}>
<App />
</ConnectedRouter>
</LanguageProvider>
</Provider>,
MOUNT_NODE,
);
};
// index.js
class App extends React.Component {
componentDidMount() {
console.log('here');
this.props.fetchUser();
}
render() {
return (
<ThemeWrapper>
<AppContext.Consumer>
.....
App.propTypes = {
fetchUser: PropTypes.any.isRequired
};
export default withRouter(connect(null, actions)(App));
import { FETCH_USER } from '../actions/types';
export default function (state = null, action) {
switch (action.type) {
case FETCH_USER:
console.log('1');
return action.payload || false;
default:
return state;
}
}
// actions
export const fetchUser = () => async dispatch => {
const res = await axios.get('/api/current_user');
// res is the output of the axios request
dispatch({ type: FETCH_USER, payload: res.data });
};
// Banner.js - auth = undefined
render() {
console.log(this.props);
// === auth = undefined. I may be accessing it incorrectly
const mapStateToProps = state => ({
gradient: state.getIn([reducerUI, 'gradient']),
chat: state.getIn([chatUI, 'chatSelected']),
auth: state.auth
});
const BannerMaped = connect(
mapStateToProps,
)(Banner);
// configure store
export default function configureStore(initialState = {}, history) {
// Create the store with two middlewares
// 1. sagaMiddleware: Makes redux-sagas work
// 2. routerMiddleware: Syncs the location/URL path to the state
const middlewares = [sagaMiddleware, routerMiddleware(history), reduxThunk];
const enhancers = [applyMiddleware(...middlewares)];
// If Redux DevTools Extension is installed use it, otherwise use Redux compose
/* eslint-disable no-underscore-dangle, indent */
const composeEnhancers =
process.env.NODE_ENV !== 'production' &&
typeof window === 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
// TODO Try to remove when `react-router-redux` is out of beta, LOCATION_CHANGE should not be fired more than once after hot reloading
// Prevent recomputing reducers for `replaceReducer`
shouldHotReload: false,
})
: compose;
/* eslint-enable */
const store = createStore(
createReducer(),
fromJS(initialState),
composeEnhancers(...enhancers),
);
// Extensions
store.runSaga = sagaMiddleware.run;
store.injectedReducers = {}; // Reducer registry
store.injectedSagas = {}; // Saga registry
// Make reducers hot reloadable, see http://mxs.is/googmo
if (module.hot) {
module.hot.accept('./reducers', () => {
store.replaceReducer(createReducer(store.injectedReducers));
});
}
return store;
}
Redux存儲更新被映射到單個組件,而不是整個應用程序。
此行表示在更新商店時,僅會重新渲染Banner
組件,而不是整個應用程序。
const BannerMaped = connect(
mapStateToProps,
)(Banner);
因此,無論您的Banner
組件在哪里,每次fetchUser()
響應成功並更新商店時,都只會重新渲染您的Banner
組件。 如果您需要重新渲染其他組件,則它們還應該使用相應的mapStateToProps
訂閱store。
您還需要在connect方法中傳遞調度動作。 就您而言,您已經執行了fetchUser()操作。 因此,您可以像這樣在connect方法中傳遞它:
const BannerMaped = connect(
mapStateToProps,
fetchUser
)(Banner);
我認為這會有所幫助。
我做的一切正確,只是沒有適當地訪問狀態對象。 盯着這個有點太久了。
const mapStateToProps = state => ({
gradient: state.getIn([reducerUI, 'gradient']),
chat: state.getIn([chatUI, 'chatSelected']),
auth: state.getIn(['auth'])
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.