我是在错误地等待还是有其他问题



我是React的新手,但不是开发人员。我参加了训练以来的第一个独立项目。我在用redux。

我创建了一个需要登录的简单列表应用程序。登录正在工作。但是。如果我登录,然后刷新,redux存储将丢失所有内容。因此,我在会话存储中设置用户的令牌来解决这个问题,这样,如果用户刷新,我就可以使用令牌从数据库中获取用户的数据。

问题似乎是,当我使用axios从基于令牌的数据库中获取用户数据时,它没有正确等待,然后继续处理页面并轰炸,因为它还没有user_id。它很爆炸,因为我正试图从this.props.auth.userId.user_id访问user_id,但由于某种原因它没有。

App.js

import React  from 'react';
import { Router, Route, Switch } from 'react-router-dom';
import { connect } from 'react-redux';
import ListItemCreate from './listitems/listItemCreate';
import ListItemEdit from './listitems/listItemEdit';
import ListItemDelete from './listitems/listItemDelete';
import ListItemList from './listitems/listItemList';
import ListItemShow from './listitems/listItemShow';
import Header from './Header';
import history from '../history';
import Login from './Login/Login';
import Register from './Login/Register';
import { signInWithToken } from '../actions';
const setToken = (userToken) => {
sessionStorage.setItem('token', JSON.stringify(userToken));
}
const getToken = () => {
//sessionStorage.removeItem('token');
const tokenString = sessionStorage.getItem('token');
if(tokenString){
const userToken = JSON.parse(tokenString);

console.log('The Token for you, madam: ' +userToken.token);
return userToken?.token;
}
return null;
} 
class App extends React.Component {
//state = { isSignedIn: null };
render(){
const isSignedIn = this.props.auth.isSignedIn;
const curToken = getToken();
console.log('curToken: '+curToken);
if(curToken && !isSignedIn){
console.log('need signInWithToken');
this.props.signInWithToken(curToken);
}
if(isSignedIn){
console.log('because isSignedIn is TRUE');
//console.log(this.props.auth);
if(!curToken){setToken({ 'token': this.props.auth.userId.token });}
const user_id = this.props.auth.userId.user_id;
const email = this.props.auth.userId.email;
const token = this.props.auth.userId.token;
console.log('isSignedId:' + isSignedIn);
console.log('user_id:'+user_id);
console.log('email:' + email);
console.log('token:' + token);
console.log('getting isSigned in');
if (isSignedIn) {
console.log('it has VALUE');
console.log(this.props.isSignedIn);
} else {
console.log('no isSignedIn');
}
}
if(curToken){console.log('curToken:' + curToken);}
//const token = getToken();
//console.log();
if(isSignedIn || curToken){
console.log('i HAVE a token');
return(
<div className="ui container">
<Router history={history}>
<div>
<Header />
<Switch>
<Route path="/" exact component={ListItemList} />
<Route path="/listitems/new" exact component={ListItemCreate} />
<Route path="/listitems/edit/:list_item_id" exact component={ListItemEdit} />
<Route path="/listitems/delete/:list_item_id" exact component={ListItemDelete} />
<Route path="/listitems/:list_item_id" exact component={ListItemShow} />
</Switch>
</div>
</Router>
</div>
);
}else{
console.log('NO token');
return(
<div className="ui container">
<Router history={history}>
<div>
<Header />
<Switch>
<Route path="/" exact component={Login} setToken={setToken} />
<Route path="/register" exact component={Register} setToken={setToken}  />

</Switch>
</div>
</Router>
</div>
);
}
}
}
const mapStateToProps = (state) => {
return { auth: state.auth };
};
export default connect(mapStateToProps, { signInWithToken })(App);

来自动作创建者(但不是整个文件(:

export const signInWithToken = (token) => async (dispatch) => {
console.log('signInWithToken');

let data = new FormData();
data.append('grant_type', 'signinwithtoken');
data.append('token', token);
const response = await user.post(`theurl/token`, data)
.then(response => {
console.log('and the response is'); // << It's showing me this in the console just AFTER the error where it needs to access the user_id
console.log(response.data);

dispatch({ type: SIGN_IN_WITH_TOKEN, payload: response.data });
history.push('/');
return {
type: SIGN_IN_WITH_TOKEN,
payload: response.data
};
});
};

减速器:

import { SIGN_IN, SIGN_OUT, LOGIN, REGISTER, SIGN_IN_WITH_TOKEN } from '../actions/types';
const INITIAL_STATE = {
isSignedIn: null,
userId: null
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case REGISTER:
return { ...state, isSignedIn: true, userId: action.payload };
case LOGIN:
return { ...state, isSignedIn: true, userId: action.payload };
case SIGN_IN:
return { ...state, isSignedIn: true, userId: action.payload };
case SIGN_OUT:
return { ...state, isSignedIn: false, userId: null };
case SIGN_IN_WITH_TOKEN:
return { ...state, isSignedIn: true, userId: action.payload };
default:
return state;
}
};

这里是ListItemList,只要存在user_id:,它就会被呈现

import React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { fetchListItems, markListItemCompleted } from '../../actions';
import MultiSort from '../MultiSort';
class ListItemList extends React.Component {
componentDidMount(){
console.log('in ListItemList');
console.log(this.props);
const id = this.props.currentUserId;
if(id){
this.props.fetchListItems(id);
}else{

}

}
markCompleted(listItem){
console.log('in markCompleted');
console.log(listItem);
// you need to pass the data, but completion datetime needs to be set
let currentdate = new Date(); 
let datetime = currentdate.getDate() + "/"
+ (currentdate.getMonth()+1)  + "/" 
+ currentdate.getFullYear() + " "  
+ currentdate.getHours() + ":"  
+ currentdate.getMinutes() + ":" 
+ currentdate.getSeconds();
console.log(datetime);        
this.props.markListItemCompleted(listItem.list_item_id);

}
renderAdmin(listItem){
// if(listItem.userId === this.props.currentUserId){
return (
<div className="right floated content">
<button className="ui button secondary" onClick={() => this.markCompleted(listItem)} >Mark {listItem.completion_label}</button>
<Link to={`/listItems/edit/${listItem.list_item_id}`} className="ui button primary">Edit</Link>
<Link to={`/listItems/delete/${listItem.list_item_id}`} className="ui button negative">Delete</Link>
</div>
);
//}
}
formatCompletedDT(dt = null){
if(dt === "0000-00-00 00:00:00"){return "Never";}
let date = new Date(dt);
let day = date.getDate();
let month = date.getMonth() + 1;
let year = date.getFullYear();
let hour = date.getHours();
let minute = date.getMinutes();
let second = date.getSeconds();
return month + '/' + day + '/' + year + ' ' + hour + ':' + minute + ':' + second;
}

renderList(){
const noNulls = this.props.listItems.map(listItem => {
if(!listItem.last_completed_dt){
listItem.last_completed_dt = "0000-00-00 00:00:00";
}
return listItem;
});
const sortedList = MultiSort(noNulls, { last_completed_dt: 'asc', list_item: 'asc'});

return sortedList.map(listItem => {
const lastCompleted = this.formatCompletedDT(listItem.last_completed_dt);
// if(listItem.userId === this.props.currentUserId){
return (
<div className="item" key={listItem.list_item_id}>
{this.renderAdmin(listItem)}
<i className="large middle aligned icon check circle" />
<div className="content">
<Link to={`/listItems/${listItem.list_item_id}`} className="header">
{listItem.list_item}
</Link>
<div className="description" style={{ color: 'grey', fontSize: '9pt' }} >Last {listItem.completion_label}: {lastCompleted}</div>
</div>
</div>
);
// }   
});
}
renderCreateButton(){
//if(this.props.isSignedIn){
return(
<div style={{ textAlign: 'right' }}>
<Link to="/listItems/new" className="ui button primary">
Create List Item
</Link>
</div>
);
//}
}
render(){
return (
<div>
<h2>List Items</h2>
<div className="ui celled list">{this.renderList()}</div>
{this.renderCreateButton()}
</div>
);
}
}
const mapStateToProps = (state) => {
return { 
listItems: Object.values(state.listItems),
currentUserData: state.auth.userId,
isSignedIn: state.auth.isSignedIn,
auth: state.auth
};
};
export default connect(mapStateToProps, { fetchListItems, markListItemCompleted })(ListItemList);

ListItemList的动作创建者:

export const fetchListItems = (userId) => async dispatch => {
const response = await listItems.get(`/listItemsMaintenance?user_id=${userId}`);
dispatch({ type: FETCH_LIST_ITEMS, payload: response.data });
};

我相信,如果我的计划有严重缺陷,你会告诉我的。

您的问题是这个if语句:if(isSignedIn || curToken){当它使用令牌进行渲染但尚未登录时,您尝试将其渲染为您已经拥有用户信息。实现在reducer中设置加载值,并在执行async之前在signInWithToken操作中将其设置为true,并在完成promise(失败或成功(时将其设置为false。

相关内容

  • 没有找到相关文章

最新更新