Search code examples
reactjstypescriptreact-nativedispatch

using dispatch on react


I am new to react and I'm trying to create a register and login page with react-redux and dispatch using the mern stack.

When I am calling the method the function did not run.

I have a file for the login page:


    import React from "react";
    import {login} from '../../actions/authActions';
    
    
    export class Login extends React.Component {
        
        constructor(props) {
            super(props);
        }
        
        checkIfElementIsEmpty = (element) => {
            if (!element) {
                return false
            }
            if (element.value.length === 0)
            {
                return false;
            }
            return true;
        }
    
        handleOnClickLogin = () =>
        {
            let usernameElement = document.getElementsByName("loginUsername")[0];
            let passwordElement = document.getElementsByName("loginPassword")[0];
    
            if (!this.checkIfElementIsEmpty(usernameElement))
            {
                usernameElement.style.backgroundColor = "#ff000042";
                return;
            }
            if (!this.checkIfElementIsEmpty(passwordElement))
            {
                passwordElement.style.backgroundColor = "#ff000042";
                return;
            }
            console.log("asd");
            login(usernameElement.value, passwordElement.value);
        }
    
        setColorToDefault = (e) =>{
            e.target.style.backgroundColor = "#f3f3f3";
        }
    
        render() {
            return <div className="base-container" ref={this.props.containerRef}>
                    <div className="header">Login</div>
                    <div className="content">
                        <div className="image">
                            {/* <img src={loginImg}/> */}
                        </div>
                        <div className="form">
                            <div className="form-group">
                                <label htmlFor="username">Username:</label>
                                <input type="text" name="loginUsername" placeholder="username" onFocus={this.setColorToDefault}/>
                            </div>
                            <div className="form-group">
                                <label htmlFor="password">Password:</label>
                                <input type="password" name="loginPassword" placeholder="password" onFocus={this.setColorToDefault}/>
                            </div>
                        </div>
                    </div>
                    <div className="footer">
                        <button type="button" className="btn" onClick={this.handleOnClickLogin}>
                            Login
                        </button>
                    </div>
                </div>
        }
    }

and a file called "authActions.js" with the function "login" that should send the request to the server and validate the login.


    export const login = (email, password) => (dispatch: Function) => {
        console.log("bbb");
        // Headers
        const config = {
            headers: {
                'Content-Type': 'application/json',
                'Access-Control-Allow-Origin': "*"
            }
        }
    
      // Request body
      const body = JSON.stringify({ email, password });
    
      axios
        .post('http://${HOST}:${PORT}/api/auth/login', body, config)
        .then(res =>
          dispatch({
            type: LOGIN_SUCCESS,
            payload: res.data
          })
        )
        .catch(err => {
          dispatch(
            returnErrors(err.response.data, err.response.status, 'LOGIN_FAIL')
          );
          dispatch({
            type: LOGIN_FAIL
          });
        });
    }

When handleOnClickLogin is called, I only see the 'aaa' on the console. The 'bbb' is never being printed. Why this is happening and how I need to use dispatch and react-redux correctly?


Solution

  • Your question needs more detail, but I'll guess and give you an overview of what it should look like.

    Redux has a connect method that basically will call a function you pass to it with a dispatch (and getState) parameter. So, given: login = (email, password) => (dispatch: Function). You call login(email, pass); and it returns a function (dispatch, [getState]) => xxx. Redux will handle it by calling it with the store's dispatch.

    For this to work, you'll also need to configure redux globally, a store, a provider, but I'm assuming your project already does that. Otherwise you'll need to go to the official docs which are really good https://react-redux.js.org/tutorials/connect

    However, if you're new to Redux and don't have all the connect set up, it'll be easier (and recommended way also) to use the Hooks API (It's also recommended in react to use Hooks rather than class components). https://react-redux.js.org/introduction/getting-started#hooks

    Back to your code, the important pieces you'll need:

    import React from "react";
    import { login } from '../../actions/authActions';
    
    import { connect } from 'react-redux';
    
    
    class MyLoginPage extends React.Component {
    
        handleOnClickLogin = () => {
         ...
         // calling the login bound by redux
         this.props.doLogin(usernameElement.value, passwordElement.value);
        } 
    
    }
    
    const LoginPageHOC = connect(null, {
      doLogin: login, // changing names for clarity (we could do login: login)
    })(MyLoginPage);
    
    export const LoginPage = LoginPageHOC; // use the HOC instead of the class