2

I am trying to achieve a dynamic form using react hooks and .map();

What I have achieved so far is to generate the form static like in this example : https://codesandbox.io/s/material-demo-ndh9q

this is my static form :

<form className={classes.root} noValidate autoComplete="off">
      <Grid container spacing={4}>
        <Grid item xs={12} sm={6} md={4}>
          <TextField id="profile" label="Name" fullWidth={true} />
        </Grid>
        <Grid item xs={12} sm={6} md={4}>
          <TextField id="profile" label="Email" fullWidth={true} />
        </Grid>
        <Grid item xs={12} sm={6} md={4}>
          <TextField id="profile" label="Address" fullWidth={true} />
        </Grid>
        {/* textarea */}
        <Grid item xs={12} sm={12} md={12}>
          <TextField
            label="Info"
            multiline
            rows={1}
            rowsMax={4}
            fullWidth={true}
          />
        </Grid>
      </Grid>
    </form>

and here I am trying to make the form dynamic:

const initialState = { name: "", email: "", address: "", info: "" };

export default function BasicTextFields() {

const [inputs, setInputs] = useState({ ...initialState });

return(
<form className={classes.root} noValidate autoComplete="off">
      <Grid container spacing={4}>
      {inputs.map((item, index) => (
        <Grid item xs={12} sm={6} md={4}>
          <TextField id={index`${item}`} label={item} fullWidth={true} />
        </Grid>
      )}
  </Grid>
    </form>
)}

but it is returning error, not sure why, can someone help me also with a detailed info please. keep in mind that also last field of the form is a textarea so gets particular attribute.

ThankYou !

1
  • If i'm not wrong, your inputs is an object, right? Commented Apr 22, 2020 at 7:31

1 Answer 1

4

I found there is some issue in your code.

  1. Since your inputs is an Object you can't directly use map on it. I've used Object.keys() to use map.
  2. Also there was some issue in your template literals.

Here is your form element with dynamic content.

<form className={classes.root} noValidate autoComplete="off">
  <Grid container spacing={4}>
    {
      Object.keys(inputs).map((key, index) => {
        if(key === 'info') {
          return (
            <Grid item xs={12} sm={12} md={12}>
            <TextField
              label={key}
              multiline
              rows={1}
              rowsMax={4}
              fullWidth={true}
            />
            </Grid>
          )
        } else {
          return (
            <Grid item xs={12} sm={6} md={4}>
          <TextField id={`index${key}`} label={key} fullWidth={true} />
        </Grid>
          )
        }
    })
  }
  </Grid>
</form>

Here is the codesandbox_link.

Sign up to request clarification or add additional context in comments.

2 Comments

and If I have multiple types of fields I guess the if condition for each, right ? Thank you :)
Yes. Welcome :)

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.