Reputation: 55
I have been learning React for a couple of weeks now and I am trying to create a react app that displays a form and when submitted, it takes the inputs and creates a madlib sentence. However when I submit the form, the GenerateMadlib component does not get rendered. Any help is appreciated! ./Madlib.js
const Madlib = () => {
const [formData, handleChange, resetFormData] = useFields({
noun: '',
noun2: '',
adjective: '',
color: ''
})
const handleSubmit = e => {
e.preventDefault();
resetFormData()
}
const generateMadlib = () => {
console.log("This line runs");
return <GenerateMadlib noun={formData.noun} noun2={formData.noun2} adjective={formData.adjective} color={formData.color} />
}
return (
<div className="Madlibs">
<h1>Madlibs!</h1>
<form
onSubmit={handleSubmit}>
<input
className="Madlibs-input"
type="text"
name="noun"
value={formData.noun}
placeholder="noun"
onChange={handleChange}/>
<input
className="Madlibs-input"
type="text"
name="noun2"
value={formData.noun2}
placeholder="nou2"
onChange={handleChange}/>
<input
className="Madlibs-input"
type="text"
name="adjective"
value={formData.adjective}
placeholder="adjective"
onChange={handleChange}/>
<input
className="Madlibs-input"
type="text"
name="color"
value={formData.color}
placeholder="color"
onChange={handleChange}/>
<button onClick={generateMadlib}>send</button>
</form>
</div>
)
}
./GenerateMadlib.js
const GenerateMadlib = ({noun, noun2, adjective, color}) => {
const madlib = Sentencer.configure({
nounList: [noun, noun2],
adjectiveList: [adjective, color]
});
return (
<>
<h1>Madlibs!</h1>
<p>{madlib}</p>
</>
)
}
Upvotes: 0
Views: 381
Reputation: 1658
Where do you want to show <Madlib />
component? Button onClick callback function cannot return component because they don't know where to show returned component. You composite components as you build blocks. Something like below code would work though I haven't tested yet.
const Madlib = () => {
const [show, setShow] = useState(false)
const [formData, handleChange, resetFormData] = useFields({
noun: '',
noun2: '',
adjective: '',
color: ''
})
const handleSubmit = e => {
e.preventDefault();
setShow(true)
resetFormData()
}
return (
<div className="Madlibs">
<h1>Madlibs!</h1>
<form>
<input
className="Madlibs-input"
type="text"
name="noun"
value={formData.noun}
placeholder="noun"
onChange={handleChange}/>
<input
className="Madlibs-input"
type="text"
name="noun2"
value={formData.noun2}
placeholder="nou2"
onChange={handleChange}/>
<input
className="Madlibs-input"
type="text"
name="adjective"
value={formData.adjective}
placeholder="adjective"
onChange={handleChange}/>
<input
className="Madlibs-input"
type="text"
name="color"
value={formData.color}
placeholder="color"
onChange={handleChange}/>
<button onClick={handleSubmit}>send</button>
</form>
{show && <GenerateMadlib noun={formData.noun} noun2={formData.noun2} adjective={formData.adjective} color={formData.color} />}
</div>
)
}
Or you may want to redirect using react-router-dom.
Upvotes: 2
Reputation: 41
Returning a component from an onClick
callback will not append the component to the DOM. Only what returns from the functional component will be appended to the DOM. So instead you should create an array that contains all the forms generated or a value that contains the current form generated and render that array via JSX.
const Madlib = () => {
const [formData, handleChange, resetFormData] = useFields({
noun: '',
noun2: '',
adjective: '',
color: ''
})
const [currentForms, setCurrentForms] = useState([])
const handleSubmit = e => {
e.preventDefault();
resetFormData()
}
const generateMadlib = () => {
console.log("This line runs");
setCurrentForms(
currentForms.push(
(<GenerateMadlib noun={formData.noun} noun2={formData.noun2} adjective={formData.adjective} color={formData.color} />)
)
) //? This updates state and re-renders with new forms
}
var currentForms = []
return (
<div className="Madlibs">
<h1>Madlibs!</h1>
<form
onSubmit={handleSubmit}>
<input
className="Madlibs-input"
type="text"
name="noun"
value={formData.noun}
placeholder="noun"
onChange={handleChange}/>
<input
className="Madlibs-input"
type="text"
name="noun2"
value={formData.noun2}
placeholder="nou2"
onChange={handleChange}/>
<input
className="Madlibs-input"
type="text"
name="adjective"
value={formData.adjective}
placeholder="adjective"
onChange={handleChange}/>
<input
className="Madlibs-input"
type="text"
name="color"
value={formData.color}
placeholder="color"
onChange={handleChange}/>
<button onClick={generateMadlib}>send</button>
</form>
{currentForms}
</div>
)
}
Note: I haven't tested this code so it might have errors
Upvotes: 0