0

I have a react application with redux. In the app there is a text field and a button. When the button is clicked an action creator is dispatched.

Here is an example of the component

import {useState} from "react";
import {useDispatch, useSelector} from "react-redux";

import updateEmail from "redux/actions/updateEmail";

const MyForm = () => {
    const [email, setEmail] = useState("")
  const dispatch = useDispatch()
  const {saving, error} = useSelector(state => state.saveEmail)

  if (saving) return <div>Please wait.....</div>

  if (error) return <div>Something has gone wrong.....</div>

  return (
      <div className="container">
          <p>Forgot Password</p>

          <input
            value={email}
            onChange={e => setEmail(e.target.value)}
            className="input is-large"
            type="text"
            placeholder="Email"
          ></input>
          <a onClick={() => dispatch(updateEmail())} className="has-text-weight-bold">Login</a>
      </div>
  );
};

export default MyForm;

when the redux state saving, error changes, the UI re-renders. The state defines what the user is displayed.

In a NextJS application, how would I go about doing this without using redux. What is the correct way without redux

  1. for the client to make rest calls similar to above
  2. the UI to re-render based on the state similar to above example
breaktop
  • 1,899
  • 4
  • 37
  • 58
  • Redux only need to be re-created on server side each call, for example to put state for auth, token, or other info from cookies inside getInitialProps for example. But once it renders page, Redux can be created with cookies too and with storage or other places, and will be remained in Memory for the rest of calls. So in your forms, it's ok to use Redux with no problem to dispatch and use states. However, you can use `React.useContext()` to manage states globally if you don't want the full power of redux. – KeitelDOG Mar 03 '21 at 20:48
  • You can take a look at those: https://github.com/vercel/next.js/tree/canary/examples/with-redux and https://stackoverflow.com/questions/60626451/is-using-redux-with-next-js-an-anti-pattern . If you don't want to use global state, you would just need to call a function that is defined inside of your component that would make the POST call with Axios for example. – KeitelDOG Mar 03 '21 at 20:51

1 Answers1

0

I don't really understand what the form is, is it for Login? I suppose it's for submitting Email for Password Reset. I commented you Answer too, so you can reconsider the Redux way for NextJS.

Anyway here is the proper way, which is the normal React way to do it in NextJS:

import { useState } from 'react';
import axios from 'axios';
// forget redux
// import {useDispatch, useSelector} from "react-redux";
// import updateEmail from "redux/actions/updateEmail";

const MyForm = () => {
  const [email, setEmail] = useState('');
  // 2 new states are created just for the form
  // const { saving, error} = useSelector(state => state.saveEmail)
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState(false);

  // the dispatch (which has a function defined at another place)
  // is replaced by a local function
  // const dispatch = useDispatch()
  const updateEmail = () => {
    setSaving(true);
    setError(false);

    axios({
      method: 'post',
      url: `https://example.com/api/submit-email`,
      headers: {
        'Content-Type': 'application/json',
      },
      data: {
        email,
      },
    })
      .then(response => {
        console.log('response login', response.data);
        // NEXT STEP
      })
      .catch(err => {
        console.log('login user error', err.response);
        setSaving(false);
        setError(true);
      });
  };

  if (saving) return <div>Please wait.....</div>;

  if (error) return <div>Something has gone wrong.....</div>;

  return (
    <div className="container">
      <p>Forgot Password</p>

      <input
        value={email}
        onChange={e => setEmail(e.target.value)}
        className="input is-large"
        type="text"
        placeholder="Email"
      />
      <a onClick={updateEmail} className="has-text-weight-bold">
        Submit Email
      </a>
    </div>
  );
};

export default MyForm;
KeitelDOG
  • 4,750
  • 4
  • 18
  • 33
  • The code I posted in the question is just generic way of handling states in react redux application. When the state changes, it causes the UI to re-render. What I wanted to know is how to do this in NextJS without Redux. Your solution seems fine but, don't you think there is too much going in your solution. Is React Redux world, the submit logic is moved out of the component and into actions and reducers. In you solution everything is in your component. Is there a cleaner way to do this is NextJS without Redux? – breaktop Mar 03 '21 at 21:54
  • In this case you can achieve the same with React Global Context. I use it with Next in 2 projects, wrapping everything within a `` in `_app.js`, using cookies to set it up in server side and client side. This way you can still use a store and dispatch to move the function into actions at other place. I can modify the answer to give you an example. Here is React Hooks `useContext` and `useReducer` : https://reactjs.org/docs/hooks-reference.html#usecontext – KeitelDOG Mar 04 '21 at 14:14