Home > Mobile >  Prefill form data in React
Prefill form data in React

Time:06-20

I have a form component in my react app that can be used to create or update recipes depending on the route. The create functionality works fine, but the update is giving me trouble.

I pass fetched data into the component using props here is what the JSON looks like:

{
   method: "Cook the guanciale in a large skillet over medium heat until deeply golden 
           (adjust the heat as necessary to render the fat [...]
   name: "Pasta Alla Gricia"
}

I am trying to get the name to prefill into the form's name <input> and the method to prefill into the form's method <textarea>. I tried doing this with useEffect(), with:

 useEffect(() => {
    setName(props.data.name)
    setMethodStepsList(props.data.method)
  })

while it prefilled the name input it then locked the value to that. The method did not prefill the textarea at all.

I am pretty stumped with this one, and would be grateful for any assistance.

export default function Recipe(props) {
  const [name, setName] = useState('')
  const [methodStepsList, setMethodStepsList] = useState('')
  const [methodStepObject, setMethodStepObject] = useState([])
  const [ingredientList, setIngredientList] = useState([])
  const [ingredientObject, setIngredientObject] = useState({
    ingredient_name: '',
    quantity: '',
    measure: '',
  })

  const formLabel = props.data ? 'Update Recipe' : 'New Recipe'
  useEffect(() => {
    setName(props.data.name)
    setMethodStepsList(props.data.method)
  })

  //new recipe logic
  [...]

  return (
    <div>
      <div className="recipe-form-container">
        <form className="recipe-form">
          <div className="page-header">
            <h1>{formLabel}</h1>
          </div>

          {/* recipe name logic */}
          <div className="recipe-title recipe-element">
            <label>Recipe Name</label>
            <input
              type="text"
              value={name}
              onChange={(e) => setName(e.target.value)}
            ></input>
          </div>

          //recipe method logic
          <div className="recipe-blurb recipe-element">
            <label>Recipe Method</label>
            <span className="method-span">
              <textarea
                rows="5"
                name="step_instructions"
                type="text"
                placeholder="Method will be split up based on new lines"
                onChange={(e) => handleMethodChange(e)}
              ></textarea>
              <button
                onClick={(e) => {
                  console.log(methodStepObject)
                  setMethodStepsList(methodStepObject)
                  e.preventDefault()
                }}
              >
                Add Method
              </button>
          
         [...]

}

CodePudding user response:

Please remove useEffect statements and try like this

const [name, setName] = useState(props.data.name)
const [methodStepsList, setMethodStepsList] = useState(props.data.method)

CodePudding user response:

You should be careful while initializing state with props in React. See React component initialize state from props

class Recipe extends React.Component {

    constructor(props) {
        super(props)
        this.state = {name:'', method:'', ingredients: []};
    }

    static getDerivedStateFromProps(props,state) {
        return {name: props.data.name, method: props.data.method};
    }

    render() {
        return <div>...</div>
    }
}
  • Related