Search code examples
javascriptreactjsfrontendconditional-renderingcontrolled-component

Conditional Rendering of Controlled Components Giving a Blank Page When False


I've been working on my first React Project, a CV application where users can input their information and generate a CV. After the user submits the form, the form should disappear and the relevant info displayed on the page. Unfortunately, nothing is displayed after the input boxes are filled, and it seems like the state values become empty after pressing the submit button. Also, the input fields disappear even before I press the submit button.

Here's the code -

import React, { useState } from 'react';

export default function Info(){
    const [person, setPerson] = useState({
    full_name: "",
    email_ID: "",
    phone_number: "",
    edit_mode: true
    });
    
    const changeHandler = (e) =>{
        setPerson({ [e.target.name] : e.target.value })
    }

    const submitHandler = (e) =>{
        e.preventDefault();
        setPerson({
            edit_mode: false
        }); 
    }
    const editHandler = (e) =>{
        setPerson({
            edit_mode: true
        })
    }
    const editContent = (
    <div>
        <form onSubmit={submitHandler} >
            <input 
                type = "text"
                value = {person.full_name}
                placeholder='Enter Your Full Name'
                onChange={changeHandler}/>
            <br/>
            <input 
                type = "email"
                value = {person.email_ID}
                placeholder='Enter Your Email ID'
                onChange={changeHandler}/>
            <br/>
            <input 
                type = "tel"
                value = {person.phone_number}
                placeholder='Enter Your Phone Number'
                onChange={changeHandler}/>
            <br/><br/>
            <button type="submit" className="submit-button">SUBMIT</button>
        </form>
    </div>
    )

    const submittedContent = (
        <div>
            <button onClick={editHandler} className="edit-button">EDIT</button>;
            <h2>{person.full_name.toUpperCase()}</h2>
            <br/>
            <p>{person.email_ID}</p>
            <p>|</p>
            <p>{person.phone_number}</p>
        </div>
    )

    return(
        <>
            {person.edit_mode ? editContent : submittedContent}
        </>
    )
}

Is there a way to fix this without involving the use of additional React Hooks, since I'm just starting out with React and want to implement this using only the useState hook. Thanks!!


Solution

  • There are few problems in your code,

    1. You are updating state without persisting the previous values in changeHandler and submitHandler . This will lead to overwriting of existing values with the values which you are setting. While setting you can spread the values and set as:

      const changeHandler = (e) => {
       const newValue = { ...person, [e.target.name]: e.target.value };
       setPerson(newValue);
      };
      
    2. You are accessing name in e.target.name but you are not giving name to the fields inside render. You can give name as:

       <input
         name="full_name"
         type="text"
         value={person.full_name}
         placeholder="Enter Your Full Name"
         onChange={changeHandler}
       />
      

    I have created a codesandbox with working example. Please check this out.

    Full code:

    import React, { useState } from "react";
    
    export default function Info() {
      const [person, setPerson] = useState({
        full_name: "",
        email_ID: "",
        phone_number: "",
        edit_mode: true,
      });
    
      const changeHandler = (e) => {
        const newValue = { ...person, [e.target.name]: e.target.value };
        setPerson(newValue);
      };
    
      const submitHandler = (e) => {
        e.preventDefault();
    
        setPerson({ ...person, edit_mode: false });
      };
      const editHandler = (e) => {
        setPerson({ ...person, edit_mode: true });
      };
      const editContent = (
        <div>
          <form onSubmit={submitHandler}>
            <input
              name="full_name"
              type="text"
              value={person.full_name}
              placeholder="Enter Your Full Name"
              onChange={changeHandler}
            />
            <br />
            <input
              name="email_ID"
              type="email"
              value={person.email_ID}
              placeholder="Enter Your Email ID"
              onChange={changeHandler}
            />
            <br />
            <input
              name="phone_number"
              type="tel"
              value={person.phone_number}
              placeholder="Enter Your Phone Number"
              onChange={changeHandler}
            />
            <br />
            <br />
            <button type="submit" className="submit-button">
              SUBMIT
            </button>
          </form>
        </div>
      );
      const submittedContent = (
        <div>
          <button onClick={editHandler} className="edit-button">
            EDIT
          </button>
          <h2>{person.full_name.toUpperCase()}</h2>
          <br />
          <p>
            {person.phone_number} | {person.email_ID}
          </p>
        </div>
      );
    
      return <>{person.edit_mode ? editContent : submittedContent}</>;
    }