在展示组件中,Redux Store 状态未定义
In presentational component, Redux Store state is undefined
我想访问展示组件中的 Redux Store State,但状态未定义。
我制作了 Container Component、Presentational Component 和 Redux Store。
所以我尝试在演示组件中访问 user
,但 user
未定义。
我在为异步 API 请求创建 Redux Store 时使用 Redux-Thunk。
令人怀疑的部分是 Rdux Store State 有一个值,但我无法访问表示组件中的状态 user
// headerState.js
import { handleActions } from 'redux-actions';
import * as api from '../lib/api';
const USER_STATE = 'headerState/USER_STATE';
const USER_STATE_SUCCESS = 'headerState/USER_STATE_SUCCESS';
const USER_STATE_FAILURE = 'headerState/USER_STATE_FAILURE';
const USER_LOGOUT = 'headerState/USER_LOGOUT';
const USER_LOGOUT_SUCCESS = 'headerState/USER_LOGOUT_SUCCESS';
const USER_LOGOUT_FAILURE = 'headerState/USER_LOGOUT_FAILURE';
export const getUserInfo = () => async (dispatch) => {
dispatch({ type: USER_STATE });
try {
const response = await api.getUser();
dispatch({
type: USER_STATE_SUCCESS,
payload: response.data,
});
} catch (error) {
dispatch({
type: USER_STATE_FAILURE,
payload: error,
error: true,
});
throw error;
}
};
export const userLogout = () => async (dispatch) => {
dispatch({ type: USER_LOGOUT });
try {
const response = await api.logout();
dispatch({
type: USER_LOGOUT_SUCCESS,
payload: response.data,
});
} catch (error) {
dispatch({
type: USER_LOGOUT_FAILURE,
payload: error,
error: true,
});
throw error;
}
};
const initialState = {
user: null,
loading: {
isProcessing: false,
},
};
const headerState = handleActions(
{
[USER_STATE]: (state) => ({
...state,
loading: {
...state.loading,
isProcessing: true,
},
}),
[USER_STATE_SUCCESS]: (state, action) => ({
...state,
user: action.payload,
loading: {
...state.loading,
isProcessing: false,
},
}),
[USER_STATE_FAILURE]: (state) => ({
...state,
loading: {
...state.loading,
isProcessing: false,
},
}),
[USER_LOGOUT]: (state) => ({
...state,
loading: {
...state.loading,
isProcessing: true,
},
}),
[USER_LOGOUT_SUCCESS]: (state, action) => ({
...state,
user: action.payload,
loading: {
...state.loading,
isProcessing: false,
},
}),
[USER_LOGOUT_FAILURE]: (state) => ({
...state,
loading: {
...state.loading,
isProcessing: false,
},
}),
},
initialState,
);
export default headerState;
// HeaderContainer.js
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import Header from './common/Header';
import { getUserInfo, userLogout } from '../modules/headerState';
const HeaderContainer = ({ user, getUserInfo, userLogout }) => {
useEffect(() => {
getUserInfo();
}, [getUserInfo]);
return <Header user={user} logout={userLogout} />;
};
const mapStateToProps = (state) => {
return {
user: state.user,
loading: state.loading,
};
};
export default connect(mapStateToProps, {
getUserInfo,
userLogout,
})(HeaderContainer);
// Header.js
(...)
const Header = ({ user, logout }) => { ** // user is undefined **
return (
<>
<TopNav>
<Link to="/" style={TitleLinkStyle}>
<NavTitle>
<img
src={logo}
width="50"
height="50"
color="white"
style={{ paddingRight: '25px', alignSelf: 'center' }}
alt="logo"
/>
Service Title
</NavTitle>
</Link>
<div style={{ display: 'flex', flex: 4 }} />
<SubNav>
<Link to="/home" style={{ textDecoration: 'none', color: 'white' }}>
<HomeDiv>Home</HomeDiv>
</Link>
{!user.snsId && (
<Link
to="/login"
style={{ textDecoration: 'none', color: 'white' }}
>
<LoginDiv>Login</LoginDiv>
</Link>
)}
{user.snsId && (
<LoginDiv onClick={logout} style={{ cursor: 'pointer' }}>
Logout
</LoginDiv>
)}
</SubNav>
</TopNav>
</>
);
};
export default Header;
有两个潜在的问题。
首先,user
的初始值为null,直到USER_STATE_SUCCESS
被调度。因此,尝试在您的演示组件中访问 user.snsId
将导致类型错误:
Cannot read property 'snsId' of undefined
您可以使用可选链接来尝试访问 snsId
并简化您的逻辑。
// Header.js
const Header = ({ user }) => {
return user?.snsId ? <div>Logout</div> : <div>Login</div>;
};
第二个问题可能在于您如何创建和访问您的商店。我假设你正在做这样的事情:
const reducers = combineReducers({
header: headerReducer
});
const store = createStore(reducers);
使用 mapStateToProps
时,您的容器组件需要通过创建它时使用的相同键访问该状态片 - header
。
// HeaderContainer.js
const mapStateToProps = (state) => {
return {
user: state.header.user, // state.user is undefined
loading: state.header.loading // state.loading is undefined
};
};
我想访问展示组件中的 Redux Store State,但状态未定义。 我制作了 Container Component、Presentational Component 和 Redux Store。
所以我尝试在演示组件中访问 user
,但 user
未定义。
我在为异步 API 请求创建 Redux Store 时使用 Redux-Thunk。
令人怀疑的部分是 Rdux Store State 有一个值,但我无法访问表示组件中的状态 user
// headerState.js
import { handleActions } from 'redux-actions';
import * as api from '../lib/api';
const USER_STATE = 'headerState/USER_STATE';
const USER_STATE_SUCCESS = 'headerState/USER_STATE_SUCCESS';
const USER_STATE_FAILURE = 'headerState/USER_STATE_FAILURE';
const USER_LOGOUT = 'headerState/USER_LOGOUT';
const USER_LOGOUT_SUCCESS = 'headerState/USER_LOGOUT_SUCCESS';
const USER_LOGOUT_FAILURE = 'headerState/USER_LOGOUT_FAILURE';
export const getUserInfo = () => async (dispatch) => {
dispatch({ type: USER_STATE });
try {
const response = await api.getUser();
dispatch({
type: USER_STATE_SUCCESS,
payload: response.data,
});
} catch (error) {
dispatch({
type: USER_STATE_FAILURE,
payload: error,
error: true,
});
throw error;
}
};
export const userLogout = () => async (dispatch) => {
dispatch({ type: USER_LOGOUT });
try {
const response = await api.logout();
dispatch({
type: USER_LOGOUT_SUCCESS,
payload: response.data,
});
} catch (error) {
dispatch({
type: USER_LOGOUT_FAILURE,
payload: error,
error: true,
});
throw error;
}
};
const initialState = {
user: null,
loading: {
isProcessing: false,
},
};
const headerState = handleActions(
{
[USER_STATE]: (state) => ({
...state,
loading: {
...state.loading,
isProcessing: true,
},
}),
[USER_STATE_SUCCESS]: (state, action) => ({
...state,
user: action.payload,
loading: {
...state.loading,
isProcessing: false,
},
}),
[USER_STATE_FAILURE]: (state) => ({
...state,
loading: {
...state.loading,
isProcessing: false,
},
}),
[USER_LOGOUT]: (state) => ({
...state,
loading: {
...state.loading,
isProcessing: true,
},
}),
[USER_LOGOUT_SUCCESS]: (state, action) => ({
...state,
user: action.payload,
loading: {
...state.loading,
isProcessing: false,
},
}),
[USER_LOGOUT_FAILURE]: (state) => ({
...state,
loading: {
...state.loading,
isProcessing: false,
},
}),
},
initialState,
);
export default headerState;
// HeaderContainer.js
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import Header from './common/Header';
import { getUserInfo, userLogout } from '../modules/headerState';
const HeaderContainer = ({ user, getUserInfo, userLogout }) => {
useEffect(() => {
getUserInfo();
}, [getUserInfo]);
return <Header user={user} logout={userLogout} />;
};
const mapStateToProps = (state) => {
return {
user: state.user,
loading: state.loading,
};
};
export default connect(mapStateToProps, {
getUserInfo,
userLogout,
})(HeaderContainer);
// Header.js
(...)
const Header = ({ user, logout }) => { ** // user is undefined **
return (
<>
<TopNav>
<Link to="/" style={TitleLinkStyle}>
<NavTitle>
<img
src={logo}
width="50"
height="50"
color="white"
style={{ paddingRight: '25px', alignSelf: 'center' }}
alt="logo"
/>
Service Title
</NavTitle>
</Link>
<div style={{ display: 'flex', flex: 4 }} />
<SubNav>
<Link to="/home" style={{ textDecoration: 'none', color: 'white' }}>
<HomeDiv>Home</HomeDiv>
</Link>
{!user.snsId && (
<Link
to="/login"
style={{ textDecoration: 'none', color: 'white' }}
>
<LoginDiv>Login</LoginDiv>
</Link>
)}
{user.snsId && (
<LoginDiv onClick={logout} style={{ cursor: 'pointer' }}>
Logout
</LoginDiv>
)}
</SubNav>
</TopNav>
</>
);
};
export default Header;
有两个潜在的问题。
首先,user
的初始值为null,直到USER_STATE_SUCCESS
被调度。因此,尝试在您的演示组件中访问 user.snsId
将导致类型错误:
Cannot read property 'snsId' of undefined
您可以使用可选链接来尝试访问 snsId
并简化您的逻辑。
// Header.js
const Header = ({ user }) => {
return user?.snsId ? <div>Logout</div> : <div>Login</div>;
};
第二个问题可能在于您如何创建和访问您的商店。我假设你正在做这样的事情:
const reducers = combineReducers({
header: headerReducer
});
const store = createStore(reducers);
使用 mapStateToProps
时,您的容器组件需要通过创建它时使用的相同键访问该状态片 - header
。
// HeaderContainer.js
const mapStateToProps = (state) => {
return {
user: state.header.user, // state.user is undefined
loading: state.header.loading // state.loading is undefined
};
};