我有React
和react-redux
这个React应用,我已经设置了自己的API。
我有这个登录页面,成功登录后返回用户对象。登录后,我想将此用户对象存储在商店中,以便我可以在其他组件中访问它。但是,它没有从另一个组件中的商店给我更新的值。
这是我的登录组件:
// Login.js
// Imports
import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as userActions from '../actions/userActions';
// Connecting to the store and passing the current user as props
@connect((state) => {
return {
user: state.user.user
}
})
class Login extends Component {
constructor() {
// This is just for the form I'm not storing the received user object in this state
super();
this.state = {
user: {},
email: "none",
password: "none",
alert: {}
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
// Change handler to update state when form input changes
const target = e.target;
const name = target.name;
const value = target.value;
this.setState({
[name]: value
})
}
handleSubmit(e) {
// Submit handler that makes request with fetch()
e.preventDefault();
// Make post request to api
const { email, password } = this.state;
// todo: fix this
var headers = new Headers();
headers.append('Accept', 'application/json'); // This one is enough for GET requests
headers.append('Content-Type', 'application/json'); // This one sends body
// Url
const url = "https://classsify-api.herokuapp.com/users/login"
fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify({
// Pass the data from the form
email: email,
password: password
})
}).then((res) => {
// Parse json
res.json().then((json) => {
// Display the message if there is one
if (json["message"]) {
const message = json["message"]["message"];
const style = json["message"]["style"];
this.setState({
alert: {
message: message,
style: style
}
});
} else if (res.status === 200) {
// Auth successfull
// Here I receive the user object
/*
This is the area of relevance!
*/
const user = json["user"];
// I'm now dispatching with the userActions.updateUser()
this.props.dispatch(userActions.updateUser(user));
console.log(this.props); // This shows the correct user object with the received data
}
});
}).catch((err) => {
console.log(err);
});
}
/* Next is my render() and other methods but they are not relevant */
export default Login;
这似乎可以胜任。但是,当我尝试在另一个组件中访问此数据(在实际登录后)时,它不起作用。
// Profile.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
// Components
import Sidebar from './Sidebar';
// Connect to the store and pass user as props
@connect((state) => {
return {
user: state.user
}
})
class Profile extends Component {
render() {
console.log("props", this.props); // user object with the DEFAULT STATE?!?!?!?!?! I DON'T UNDERSTAND HAHA
return(
<div>
<Sidebar location={this.props.location}/>
<main role="main" className="col-sm-9 ml-sm-auto col-md-10 pt-3">
<h1>Hi</h1>
<hr/>
</main>
</div>
);
}
}
export default Profile;
这是我的商店:
// store.js
import { createStore } from 'redux';
import reducer from './reducers';
const store = createStore(reducer);
export default store;
我的用户减速机:
const userReducer = (state={}, action) => {
switch (action.type) {
case "UPDATE_USER":
console.log("YEAH");
return {...state, user: action.payload}
break;
default:
return state;
}
}
export default userReducer;
我的合并减速器:
// combined reducer
import { combineReducers } from 'redux';
import user from './userReducer';
export default combineReducers({
user
});
我的用户操作:
// user actions
export function updateUser(user) {
return {
type: “UPDATE_USER”,
payload: user
}
}
和Index.js:
// Index and main component
import App from ‘./App.js’;
import { Provider } from ‘redux’;
import ReactDOM from ‘react-dom’;
// Some other import like css files...
import store from ‘./store’
const root = document.getelementById(“root”);
ReactDOM.render(<Provider store={store}><App /><Provider/>, root)
最后我的Navbar组件:
// Navbar.js
import React, { Component } from 'react';
class Navbar extends Component {
render() {
return (
<nav className="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a className="navbar-brand" href="/"><i className="fa fa-graduation-cap" aria-hidden="true"></i> Classify</a>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mr-auto">
<li className="nav-item active">
<a className="nav-link" href="/">Home <span className="sr-only">(current)</span></a>
</li>
<li className="nav-item">
<a className="nav-link" href="/about">About</a>
</li>
</ul>
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<a href="/" className="nav-link">Dashboad</a>
</li>
</ul>
</div>
</nav>
);
}
}
export default Navbar;
答案 0 :(得分:1)
问题出在Navbar组件中。
您使用的是<a>
代码,该代码会导航到href
属性指定的新页面。
这会导致您的应用重新加载/刷新,从而重置您的应用程序状态。
使用react-router-dom的链接组件可以解决您的问题。请参阅下面的“关于”链接所做的更改:
import React, { Component } from 'react';
import {Link} from 'react-router-dom';
class Navbar extends Component {
render() {
return (
<nav className="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a className="navbar-brand" href="/"><i className="fa fa-graduation-cap" aria-hidden="true"></i> Classify</a>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mr-auto">
<li className="nav-item active">
<a className="nav-link" href="/">Home <span className="sr-only">(current)</span></a>
</li>
<li className="nav-item">
<Link className="nav-link" to="/about">About</Link>
</li>
</ul>
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<a href="/" className="nav-link">Dashboad</a>
</li>
</ul>
</div>
</nav>
);}
}
export default Navbar;
另外,如果您可以将Navbar组件上传到您的问题中,那么其他人就可以看到原来的内容了!