javascript - Redux 存储未在全局范围内更新

标签 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;

还有我的组合 reducer :

// 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.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;

最佳答案

问题出在您的导航栏组件中。 您正在使用<a>标签,导航到 href 指定的新页面属性。 这会导致您的应用程序重新加载/刷新,从而重置您的应用程序状态。

使用react-router-dom的Link组件将解决你的问题。请参阅下面对“关于”链接所做的更改:

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;

此外,如果您可以将导航栏组件上传到您的问题,以便其他人可以看到原始内容,那就太好了!

关于javascript - Redux 存储未在全局范围内更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47742076/

相关文章:

javascript - this.context 返回一个空对象

javascript - 等待 Ext.Ajax.request 成功响应后再设置变量

javascript - 异步 promise 中未处理的 promise 拒绝

javascript - 使用ajax设置react组件的初始状态

javascript - 多个组件状态的 react 钩子(Hook)没有更新

node.js - 流+Webstorm "Cannot resolve module"

javascript - 如何修复 React Redux 和 React Hook useEffect 缺少依赖项 : 'dispatch'

javascript - Node.js 中的异常处理程序

javascript - Material-UI 数据网格仅呈现 101 行

javascript - 如何让多个提供者或状态仅可用于布局的一部分