Mam trasę w Express i chciałbym zadzwonić do działania importowanego z mojego reduktora:

/* 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 };
};

I to jest moja trasa:

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);
  }
});

Próbowałem ustawić hasBeenVerified(); console.log('hasBeenVerified()', hasBeenVerified());

I zwraca wyjście w terminalu:

hasBeenVerified(); { type: 'IS_ACOUNT_VERIFIED' }

Ale nie zmienia stanu początkowego sklepu.

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

Jakieś myśli, jak to naprawić?

0
Antonio Pavicevac-Ortiz 22 marzec 2020, 00:24

1 odpowiedź

Najlepsza odpowiedź

Jak stwierdzono w komentarzach, musisz:

  • Wyślij niezbędne części swojego stanu frontend do zaplecza
  • Twoje zaplecze weryfikuje przy użyciu danych, które zostało wysłane
  • Backend reaguje status weryfikacyjny do swojego frontu
  • Frontend wykorzystuje to dane weryfikacyjne do aktualizacji Redux

Zobacz tutaj Demo na żywo

Poniżej znajdują się "mięso i ziemniaki" tego, co jest potrzebne do przedstawienia powyższych kroków. Chociaż, Opublikowałem cały kod, który napisałem w następującym Github Repo - Proponuję, abyś go rozwidał i uruchomić go lokalnie, aby naprawdę uzyskać punkt na całym świecie ..

Backend:

serwer.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}`);
});

frontend:

app.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);
1
Matt Oestreich 22 marzec 2020, 01:24