I am building a simple todo-esk feature where if a user clicks the edit icon, only that item is editable. I implement this currently with a useState hook, const [editingMemberName, setEditingMemberName] = useState(false), but when I call a function, editMemberName all instances of items show an input field. This is not the experience I am going for.
Here are some screen shots that should make this more clear:

As you can see, I have two cards, but when I click the tool icon, both input boxes are displayed.
Here is the code:
const [editingMemberName, setEditingMemberName] = useState(false)
const [memberName, setMemberName] = useState('')
const handleChangeName = (e) => {
setMemberName(e.target.value)
}
// Update member name
const editMemberName = async (e) => {
setEditingMemberName(true)
}
const memberItems = members.map((member) => {
return (
<div
key={member.id}
>
<div className="flex items-center gap-4 w-full">
{editingMemberName ? (
<input
type="text"
placeholder="Johnny Appleseed"
onChange={handleChangeName}
/>
) : (
<>
<div>
{member.name}
</div>
<h3>{member.name}</h3>
</>
)}
</div>
<div>
{editingMemberName ? (
<button
onClick={() => updateMemberName(member.id)}
>
<CgCheckO size=".75em" />
</button>
) : (
<button
onClick={() => editMemberName(member.id)}
>
<FiTool size=".75em" />
</button>
)}
</div>
</div>
)
I've realized that editingMemberName hook operates on all instances, but I am not sure how to only target a single item.
Note: you can assume that the members array has a unique id for each item.
members: [
{
name: "Johnny",
id: 123
},
{
name: "George",
id: 456
}
]
That's because you are referring the boolean to all the boxes and not an individual element, use
const [editingMemberName, setEditingMemberName] = useState(members.map(e => false))
Something along the lines
const editMemberName = async (memberID, index) => {
let new_editing_members_state = members.map(e => false)
new_editing_members_state[index] = true
setEditingMemberName(new_editing_members_state)
}
const memberItems = members.map((member, index) => {
return (
<div
key={member.id}
>
<div className="flex items-center gap-4 w-full">
{editingMemberName ? (
<input
type="text"
placeholder="Johnny Appleseed"
onChange={handleChangeName}
/>
) : (
<>
<div>
{member.name}
</div>
<h3>{member.name}</h3>
</>
)}
</div>
<div>
{editingMemberName[index] ? (
<button
onClick={() => updateMemberName(member.id)}
>
<CgCheckO size=".75em" />
</button>
) : (
<button
onClick={() => editMemberName(member.id,index)}
>
<FiTool size=".75em" />
</button>
)}
</div>
</div>
)