Home > Back-end >  ReactJs : Show or hide input fields based on select value
ReactJs : Show or hide input fields based on select value

Time:12-15

I'm working on a form where some additional inputs will be shown based on the value of select. The value of select changes on selecting a different option, but the "numberOfUsers" text field does not become visible.

I can see the changed value being printed on the console. Yes is printed on selecting first option and No on selecting the select.

I don't understand why it doesn't work. Please let me know the mistakes I have done.

Below is the code I have written

import React from 'react'
import { useState } from 'react'
import { Grid } from '@mui/material'
import './Form.css'

export const AddStartupForm = () => {

    const [fields, setFields] = useState({})

    function handleChange(event) {
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;
        
        fields[name] = value
        setFields(fields)
        console.log(fields['revenueGenerated'])
    }

    
    return (
        <Grid container sx={{py: 5}}>
        <Grid item xs={1} sm={4}></Grid>
        <Grid item xs={10} sm={4}>
            <form>
                <label htmlFor="startupName">Startup Name</label>
                <input type="text" 
                    name="startupName"                     
                    onChange={handleChange}
                    value={fields["startupName"]}
                />

                <label htmlFor="countryName">Country</label>                
                <input type="text" 
                    name="countryName"                     
                    onChange={handleChange}
                    value={fields["countryName"]}
                />            

                <label htmlFor="revenueGenerated">Do you make revenue?</label>
                <select name="revenueGenerated"
                    onChange={handleChange}
                    value={fields["revenueGenerated"]}
                >
                    <option disabled selected value=''> -- select an option -- </option>
                    <option value="Yes">Yes</option>
                    <option value="No">No</option>
                </select>

                { fields['revenueGenerated'] === 'Yes' ?
                   <>
                       <label htmlFor="numberOfUsers">Sample Yes</label>
                       <input type="text"
                           name="numberOfUsers"
                       />
                   </>
                   : null
               } 
                
            </form>            
        </Grid>
        </Grid>
    )
}


CodePudding user response:

fields is an object and updating a prop on that object does not change the reference to the object so react's equality check will not recognize a change (and therefore won't rerender).

Try changing

        fields[name] = value
        setFields(fields)

to

        setFields({...fields, [name]: value})

CodePudding user response:

The state isn't updated, because the reference of the state doesn't change. You can try that by adding a console.log before your return statement:

  console.log(fields);

  return (...)

It never changes.

Try setting your fields like this:

function handleChange(event) {
    const target = event.target;
    const value = target.type === "checkbox" ? target.checked : target.value;
    const name = target.name;

    
    setFields({
      ...fields,
      [name]: value
    });
  }

If you change your handler to use useCallback, be sure to add the fields as a dependency, so it get's changed:

const handleChange((event) => { 

    const target = event.target;
    const value = target.type === "checkbox" ? target.checked : target.value;
    const name = target.name;


    setFields({
      ...fields,
      [name]: value
    });


 }, [fields]);

  • Related