reactjs - React/Redux 不更新状态
问题描述
我刚开始使用 redux,我想将它包含在我现有的应用程序中。我想要做的是store
我的登录响应让我使用其他页面上的用户详细信息。
登陆页面.js
import { useDispatch } from 'react-redux'
function LandingPage(){
const dispatch = useDispatch();
const authLogin = async()=>{
const response = await axios.get('/api',)
let responseValue = response.data.success
if(responseValue === true) {
const parsedData = JSON.parse(response.data.resp)
dispatch({
type: 'SAVE_AUTH',
payload: {
isLoggedIn: responseValue,
username: parsedData.data.user.userName,
token: parsedData.data.token
}
})
}
useEffect(() => {
authLogin();
}, [])
return (
<div>
<label>Authenticating....</label>
<Login1 /> //updated based on @LindaPaiste's answer
</div>
export default LandingPage;
MainLanding.js
import React from 'react'
import Login1 from './Login1'
function MainLanding(){
return(
<div>
<h1>User Login Details</h1>
<Login1 /> //Nothing hapens here
</div>
)
}
export default MainLanding;
登录1.js
import React from 'react'
import LoginDetailsx from './LoginDetailsx'
import { useSelector } from 'react-redux'
function Login1(){
const userLoginDetails = useSelector((state) => state.loginDetails)
console.log('userLoginDetails',userLoginDetails)
return(
<div>
<h2>Login Details</h2>
<LoginDetailsx isLogin={userLoginDetails.isLoggedIn} username={userLoginDetails.username} token={userLoginDetails.token}/>
})}
</div>
)}
export default Login1;
loginDetailsReducer.js
const initialState = [
{
isLoggedIn: false,
}];
const loginDetailsReducer = (state = initialState, action) => {
const { type, payload } = action;
console.log('typex',type)
console.log('payloadx',payload)
switch(type){
case "SAVE_AUTH":
alert('dasdasd')
return payload;
case "LOGOUT_AUTH":
return initialState
default:
return state;
}
}
export default loginDetailsReducer;
rootReducer.js
import { combineReducers } from 'redux'
import loginDetailsReducer from '../reduxReducers/loginDetailsReducer'
const rootReducer = combineReducers({
loginDetails: loginDetailsReducer
});
export default rootReducer;
store.js
import { createStore } from 'redux'
import rootReducer from '../reduxReducers/rootReducer'
const store = createStore(rootReducer);
export default store;
LoginDetailsx.js
import React from 'react'
function LoginDetailsx(props){
return(
<div>
<p>Details: isloggedin: {props.isloggedin}, username: {props.username}, token: {props.token}</p>
</div>
)
}
export default LoginDetailsx;
解决方案
状态形状
虽然不一定是问题,但loginDetails
状态应该是array
. 一次只能登录一个用户,因此它应该只是一个包含用户详细信息的对象。这让你的 reducer 变得非常简单(Redux Toolkit总是可以让它变得更简单)。
您还需要添加一个注销案例。 isLoggedIn
应该是 aboolean
而不是 a string
。我个人认为这比没有登录用户时更有意义,但这取决于undefined
你''
。username
token
const initialState = {
isLoggedIn: false,
// no username or token when logged out
};
const loginDetailsReducer = (state = initialState, action) => {
const { type, payload } = action;
switch(type) {
case "SAVE_AUTH":
// replace the state with the action payload
return payload;
case "LOGOUT_AUTH":
// revert to initial state
return initialState;
default:
return state;
}
}
export default loginDetailsReducer;
在登录
我要说的是,像 API 调用这样的异步操作需要useEffect
在组件的钩子中完成。您可以在安装组件时使用一个空的依赖数组来运行一次效果。
useEffect(() => {
authLogin();
}, []);
但是现在我正在查看您的图像,您似乎正在执行操作以响应按钮单击,所以这也很好。
axios
处理 JSON 解析,因此您不需要使用JSON.parse()
(除非您的 API 返回奇怪的数据)。
function MainLanding() {
const isLoggedIn = useSelector((state) => state.loginDetails.isLoggedIn);
// access dispatch function
const dispatch = useDispatch();
// define the function to log in
const authLogin = async () => {
const response = await axios.get("/api");
const data = response.data;
if (data.success === true) {
dispatch({
type: "SAVE_AUTH",
payload: {
isLoggedIn: true,
username: data.resp.user.userName,
token: data.resp.data.token
}
});
}
};
return (
<div>
{isLoggedIn ? (
<>
<h1>User Login Details</h1>
<Login1 />
</>
) : (
<button onClick={authLogin}>Log In</button>
)}
</div>
);
}
推荐阅读
- java - 我可以像这样将带有 Map 的 3 个点放入方法参数中吗: private Map addAllMood(Map...map)
- javascript - Cheerio 加载字符串而不替换内部脚本内容
- node.js - 天蓝色事件的相关ID
- python - 二进制数的语法格式
- docker - Filecoin Textileio Powergate 没有足够的矿工来自声誉模块来满足约束错误
- github - GitHub 归档过时的文件
- java - 在单例中使用同步块
- arrays - 特定索引 mongodb 上的数组到数组连接
- azure - Azure Datalake Storage 列出容器中的第一级目录
- javascript - 未在 ui 中呈现的数据在使用 useEffect 做出反应