繁体   English   中英

是否可以从 Express 中的路由调用我的减速器中的操作函数?

[英]Is it possible to call an actions function in my reducer from a route in Express?

我在 Express 中有一条路线,我想调用从我的减速器导入的动作函数:

/* initial state */
export var usersStartState = {
  isAccountVerified: false,
};

/* action types */
export const actionTypes = {
  IS_ACCOUNT_VERIFIED: 'IS_ACCOUNT_VERIFIED',
};

/* reducer(s) */
export default function users(state = usersStartState, action) {
  switch (action.type) {
    case actionTypes.IS_ACCOUNT_VERIFIED:
      return Object.assign({}, state, { isAccountVerified: true });
    default:
      return state;
  }
}

/* actions */
export const hasBeenVerified = () => {
  return { type: actionTypes.IS_ACCOUNT_VERIFIED };
};

这是我的路线:

var router = require('express').Router();
var passport = require('passport');
var User = require('../models/UserModel');
var Token = require('../models/TokenSchema');
import { hasBeenVerified } from '../../store/reducers/users/index';

import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

router.route('/confirmation/:token').get((req, res, next) => {
  var usersToken = req.params.token;
  try {
    Token.findOne({ token: usersToken }, function(err, token) {
      if (err)
        return res.status(404).send({
          type: 'not-verified',
          msg: 'We were unable to find a valid token. Your token my have expired.'
        });
      // If we found a token, find a matching user
      User.findOne({ _id: token._userId, email: req.body.username }, function(err, user) {
        if (err)
          return res
            .status(404)
            .send({ msg: 'We were unable to find a user for this token.' });
        if (user.isVerified)
          return res.status(400).send({
            type: 'already-verified',
            msg: 'This user has already been verified.'
          });

        // Verify and save the user
        user.isVerified = true;
        user.save(function(err) {
          if (err) {
            return res.status(500).send({ msg: err.message });
          }
        });
      });
      hasBeenVerified(); // firing it here
      console.log('hasBeenVerified();', hasBeenVerified());
      res.redirect('/confirmed');
    });
  } catch (err) {
    return next(err);
  }
});

我试图设置一个hasBeenVerified(); console.log('hasBeenVerified()', hasBeenVerified()); hasBeenVerified(); console.log('hasBeenVerified()', hasBeenVerified());

它确实在终端中返回了一个输出:

hasBeenVerified(); { type: 'IS_ACOUNT_VERIFIED' }

但它不会改变商店的初始状态。

export var usersStartState = {
  isAccountVerified: false, //still false after the `hasBeenVerified` executed
};

任何想法如何解决这个问题?

如评论中所述,您将需要:

  • 将前端状态的必要部分发送到后端
  • 您的后端使用它发送的数据进行验证
  • 后端以验证状态响应您的前端
  • 前端使用此验证数据更新 Redux

在此处查看现场演示

以下是概述上述步骤所需的“肉和土豆”。 虽然,我已经发布了我在以下 GitHub 存储库中编写的所有代码- 我建议您分叉它并在本地运行它以真正理解这一点。

后端:

服务器.js

const express = require('express');
const cors = require('cors');

const app = express();
const port = 8002;

app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cors());

app.post('/authorize', (req, res) => {
    if (req.body.un === 'a' && req.body.pw === 'a') {
        res.status(200).send('true');
    } else {
        res.status(200).send('false');
    }
});

// For 404
app.use((req, res) => {
    res.status(404).send("Unable to find that!");
});

app.listen(port, () => {
    console.log(`Server listening on port ${port}`);
});

前端:

应用程序.js

import React, { Component } from "react";
import { BrowserRouter, Link } from "react-router-dom";
import Routes from "./Routes";
import withRedux from "./Redux/containers";

class App extends Component {
  state = {
    un: "",
    pw: ""
  };

  handleUnInput = event => {
    this.setState({
      ...this.state,
      un: event.target.value
    });
  };

  handlePwInput = event => {
    this.setState({
      ...this.state,
      pw: event.target.value
    });
  };

  handleLogout = () => {
      this.props.setAccountStatus(false);
  }

  handleLogin = () => {
    fetch("http://localhost:8002/authorize", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ un: this.state.un, pw: this.state.pw })
    })
      .then(res => res.text())
      .then(data => {
        if (data === "true") {
          this.props.setAccountStatus(true);
        } else {
          alert("Incorrect credentials!");
        }
      })
      .catch(err => console.log("Something went wrong! " + err.message));
  };
  render() {
    const { isAccountVerified } = this.props.state;

    return (
      <BrowserRouter>
        <Link to="/">Home</Link>
        <br />
        <Link to="/protected">Protected</Link>
        <div style={{ margin: '40px' }}>
          {isAccountVerified ? (
            <button onClick={this.handleLogout}>Logout</button>
          ) : (
            <React.Fragment>
              <p>
                Try to visit the 'Protected' route above. Unless you are logged
                in it won't work.
              </p>
              Username:
              <input type="text" onInput={this.handleUnInput} />
              <br />
              Password:
              <input type="password" onInput={this.handlePwInput} />
              <br />
              <small>Username is 'a' password is 'a'</small>
              <br />
              <button onClick={this.handleLogin}>Login</button>
            </React.Fragment>
          )}
        </div>
        <Routes />
      </BrowserRouter>
    );
  }
}

export default withRedux(App);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM