1

Hello guys so i tried to make global state so the other page can use the state. The problem is i got an error that says:

Login.js:18 Uncaught TypeError: Cannot destructure property 'emailLog' of '(0 , react__WEBPACK_IMPORTED_MODULE_0__.useContext)(...)' as it is undefined.

Im doing this because i want the email from user after logged in and pass them to another page so that i can display the logged in user.

App.js:

export const EmailUser = React.createContext();

function App() {
  Axios.defaults.withCredentials = true;

  const [invoice, setInvoice] = useState("");
  const [currency, setCurrency] = useState("IDR");
  const [myFile, setMyFile] = useState("");
  const [emailLog, setEmailLog] = useState("");

  return (
    <EmailUser.Provider value={{ emailLog, setEmailLog }}>
      <div className="App">
        <BasicExample />
        <div className="formInput">
          <form method="POST" encType="multipart/form-data" action="http://localhost:3001/upload">
            <div className="textUser"></div>

            <input
              className="inputForm"
              defaultValue={emailLog}
              type="email"
              disabled
              name="email"
            />

            <input className="inputForm" type="number" placeholder="Invoice No" name="InvoiceNo" />

            <input className="inputForm" type="date" name="Invoice_Date" />

            <input className="inputForm" type="text" placeholder="Description" name="Description" />

            <select
              className="selectBox"
              name="Currency"
              onChange={(e) => {
                setCurrency(e.target.value);
              }}
            >
              <option value="IDR">IDR</option>
              <option value="USD">USD</option>
              <option value="YEN">YEN</option>
            </select>

            <input className="inputForm" type="number" placeholder="Amount" name="Amount" />

            <input
              className="custom-file-upload"
              multiple
              type="file"
              name="DocumentFile"
              onChange={(e) => {
                setMyFile(e.target.value);
              }}
            />

            <button className="btnSubmit">Submit</button>
          </form>
        </div>
      </div>
    </EmailUser.Provider>
  );
}

export default App;

Login.js

const Login = () => {
  let navigate = useNavigate();

  const { emailLog, setEmailLog } = useContext(EmailUser);
  const [passwordLog, setPasswordLog] = useState("");

  const [loginStatus, setLoginStatus] = useState("");

  Axios.defaults.withCredentials = true;

  const login = (e) => {
    e.preventDefault();
    Axios.post("http://localhost:3001/login", {
      email: emailLog,
      password: passwordLog,
    }).then((response) => {
      console.log(response);

      if (response.data.message) {
        alert(response.data.message);
      } else {
        setLoginStatus(response.data[0].email);
        alert("Redirecting");
        navigate("/home");
      }
    });
  };
  console.log(emailLog);

  useEffect(() => {
    Axios.get("http://localhost:3001/login").then((response) => {
      if (response.data.loggedIn == true) {
        setLoginStatus(response.data.email[0].email);
      }
    });
  });

  return (
    <div>
      <img className="wave" src={Wave} />
      <img className="wave2" src={WaveV2} />
      <div className="wrapper">
        <div className="img">{/* <img src={Background}/> */}</div>

        <div className="register-content">
          <div className="registerForm">
            <img src={Avatar} />
            <h2 className="title">Welcome</h2>
            <div className="input-div one">
              <div className="i">
                <i className="fas fa-user">
                  <GrMail />
                </i>
              </div>
              <div className="div">
                <input
                  type="email"
                  className="input"
                  placeholder="Email"
                  required
                  onChange={(e) => {
                    setEmailLog(e.target.value);
                  }}
                />
              </div>
            </div>
            <div className="input-div pass">
              <div className="i">
                <i className="fas fa-lock">
                  <AiFillLock />
                </i>
              </div>
              <div className="div">
                <input
                  type="password"
                  className="input"
                  placeholder="Password"
                  required
                  onChange={(e) => {
                    setPasswordLog(e.target.value);
                  }}
                />
              </div>
            </div>
            <a href="/">Don't have an account ?</a>
            <button type="submit" className="btn" onClick={login}>
              Login
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Login;

1 Answer 1

1

EmailUser context works only with the components that are children of EmailUser.Provider, and it doesn't seem to be the case for Login component. An easy way is to create a separate component, in some EmailUserProvider.js, like so:

import {createContext, useState} from "react"
export const EmailUser = createContext();
export default function EmailUserProvider({children}) {
  const [emailLog, setEmailLog] = useState("");
  return (
    <EmailUser.Provider value={{ emailLog, setEmailLog }}>
     {children}
    </EmailUser.Provider>
  );
}

And make it wrap all the components that would consume it. If I assume all my components and routes are rendered in App and want the context to be global, I would do so:

<EmailUserProvider>
  <App/>
</EmailUserProvider>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.