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>
}
}