简体   繁体   中英

How can i create a separate folder in REACT for my Axios routes, that are connected to my node.js

Hello I trying to create a separate folder for my axios routes. I do not want them inside of my components file in React.

I have tried this under the following folder, separate from my components folder. src > actions > authentication

import axios from 'axios';

export const signupUser = (user, history) => dispatch => {
  axios.post('http://localhost:3000/signup', user)
  console.log(user)
    .then(res => history.push('/login'))
    .catch(err => {
      console.log(err);

    });
};

Inside the Signup.js component I have the following, that is not currently working

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { signupUser } from '../actions/authentication';
import axios from 'axios';

let today = new Date();
let date = today.getFullYear()+ '-' +  (today.getMonth()+1)+ '-' +today.getDate();




class Signup extends Component {

  constructor() {
    super()
    this.state = {
      first_name: '',
      last_name: '',
      user_name: '',
      email: '',
      password: '',
      created_on: date,
      isSignedup: false
    }

    this.handleInputChange = this.handleInputChange.bind(this);

    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleInputChange = (e) => {
    this.setState({
      [e.target.name]: e.target.value
    })
    console.log(this.state);
  }

  handleSubmit = (e) => {
    e.preventDefault();

    const user = {

      first_name: this.state.first_name,
      last_name: this.state.last_name,
      email: this.state.email,
      user_name: this.state.user_name,
      password: this.state.password,
      created_on: this.state.created_on,
      isSignedup: !this.state.isSignedup
    }
    .then(data => {
      console.log(data);
      this.props.history.replace('/login');
    })
    .catch(err => {
      console.log(err);
    })
  }

It only works in my components > Signup.js if I have the actual axios route inside the component as follows:

handleSubmit = (e) => {
    e.preventDefault();

    axios.post('http://localhost:3000/signup', {

      first_name: this.state.first_name,
      last_name: this.state.last_name,
      email: this.state.email,
      user_name: this.state.user_name,
      password: this.state.password,
      created_on: this.state.created_on,
      isSignedup: !this.state.isSignedup
    })
    .then(data => {
      console.log(data);
      this.props.history.replace('/login');
    })
    .catch(err => {
      console.log(err);
    })
  }

The error I keep receiving is that .then is not a function. Can someone please help me with this issue? Thank you in advance.

You are getting the error .then is not a function because of this code:

const user = {

  first_name: this.state.first_name,
  last_name: this.state.last_name,
  email: this.state.email,
  user_name: this.state.user_name,
  password: this.state.password,
  created_on: this.state.created_on,
  isSignedup: !this.state.isSignedup
}
.then

That's not valid javascript. Assigning an object to a variable does not create a promise. You have to actually call on signupUser .

Furthermore, I don't understand why you pass dispatch into your signup function if you are never calling on it?

You are on the right track with your thinking as it makes the design of your application a bit more modular.

You could create a folder called apis/ , it doesn't have to be called that but I am just giving you an example. Then inside of there create a file called myjson.js , again call it what you think its best. Inside that folder you will have something like this:

import axios from "axios";

export default axios.create({
  baseURL: "https://api.myjson.com"
});

Then you could implement that inside your action creator as myJson.post()

You could also do something like this:

import React, { Component } from "react";
import axios from "axios";

const ROOT_URL =
  "https://exampleurl.com";

class SignUpForm extends Component {
  state = { phone: "" };

  handleSubmit = () => {
    axios
      .post(`${ROOT_URL}/createUser`, {
        phone: this.state.phone
      })
      .then(() => {
        axios.post(`${ROOT_URL}/requestOneTimePassword`, {
          phone: this.state.phone
        });
      });
  };

The above of course is based on a one time password type of authentication so tailor it to the logic of your architecture.

Also, if you are going to use a constructor function with super(props) you need to pass props into it like I just did.

You can avoid all that by using ES7 and just assigning

state = {
  first_name: '',
  last_name: '',
  user_name: '',
  email: '',
  password: '',
  created_on: date,
  isSignedup: false
}

You are already using an arrow function in your handleSubmit , so there is no need to do this: this.handleSubmit = this.handleSubmit.bind(this); The arrow function is taking care of the context of this .

We can take it further and refactor that handleSubmit function to look cleaner by using ES7 async/await syntax like so:

handleSubmit = async () => {
 await axios.post(`${ROOT_URL}/createUser`, {
   phone: this.state.phone
 });
 await axios.post(`${ROOT_URL}/requestOneTimePassword`, {
   phone: this.state.phone
 });
};

And to handle errors, since we are using async/await, we can wrap everything awaited with a try/catch block like so:

handleSubmit = async () => {
    try {
      await axios.post(`${ROOT_URL}/createUser`, {
        phone: this.state.phone
      });

      await axios.post(`${ROOT_URL}/requestOneTimePassword`, {
        phone: this.state.phone
      });
    } catch (err) {
      console.log(err);
    }
  };

So this way you can catch and console log the error.

And try/catch is not new with ES2015/16/17, its been around for awhile.

Essentially, whenever you want to handle errors thrown by a request managed by the await statement we can wrap it with try/catch statement.

The failed network request response will be passed in as the error object and we can console log it to see what happens.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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