Reputation: 457
I am working with a form in react, and what I would like is that when I click a button, I add a new component which is just an input to the screen. It all mostly works, as planned. The issue is with the following: the layout is that I have one main component, which then displays a child component. That child component is called from a map of a useState. (More after code snippet)
This is the code of the main component:
import React, { useState } from "react";
import SingleProfile from "./individual_profile";
const ProfileInformation = (props) => {
console.log("proflie render");
const [ProfilesBoolean, setProfilesBoolean] = useState(false);
const [profiles, setProfiles] = useState(props.Data['profiles'])
const FieldAdd = (event)=>{
event.preventDefault();
const copy = profiles;
copy.push({Network:'',url:''})
return(copy)
}
function CreateInput(){
return profiles.map((data, index) =><SingleProfile index={index} data={data} />)
}
const accordion = (event) => {
const NextElement = event.target.nextElementSibling;
if (!event.target.className.includes("display")) {
NextElement.style.maxHeight = NextElement.scrollHeight + "px";
} else {
NextElement.style.maxHeight = 0;
}
};
return (
<div className="AccordionItem">
<div
className={
ProfilesBoolean ? "AccordionHeader-display" : "AccordionHeader"
}
onClick={(e) => setProfilesBoolean(!ProfilesBoolean)}
id="ProfileForm"
>
Profiles
</div>
<div className="AccordionContent">
<div className="AccordionBody">
{
profiles.map((data, index) => (
<SingleProfile index={index} data={data} />
))
}
<button id="ProfileAdd" onClick={(e) => {setProfiles(FieldAdd(e))}}>
Add a profile
</button>
</div>
</div>
</div>
);
};
export default ProfileInformation;
When I click the button and onClick fires FieldAdd()
the useState updates, with a new empty object as expected. However, it does not appear inside my <div className="AccordionBody">
as I would expect it to.
The following code is used to display components, by opening and closing the child div. When it is open is when you see the child components and the add button. If I click the div, to close and then click again to re-open it, the new child component appears.
<div
className={ProfilesBoolean ? "AccordionHeader-display" : "AccordionHeader"}
onClick={(e) => setProfilesBoolean(!ProfilesBoolean)}
id="ProfileForm"
>
Profiles
</div>;
Is it possible to have the child component appear without having to close and re-open the div?
Upvotes: 0
Views: 108
Reputation: 13682
Your clickHandler FieldAdd
is incorrect. You are mutating the state directly which will not cause re-render.
use setProfiles
to update the state in the clickHandler. Like this
const FieldAdd = (event)=>{
setProfiles(prev => [...prev, {Network:'',url:''}])
}
Trigger the onClick like this
<button id="ProfileAdd" onClick={(e) => {FieldAdd(e)}}>
Add a profile
</button>
...
Upvotes: 1