Redux商店未在全球范围内更新

时间:2017-12-10 18:28:18

标签: javascript reactjs react-redux

我有Reactreact-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;

1 个答案:

答案 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组件上传到您的问题中,那么其他人就可以看到原来的内容了!