Mr. Hankey
Mr. Hankey

Reputation: 1214

Edit button should only be able to be applied to one item in the list

I have a list with several objects. Each object has its own button. One is an edit button and the other is a save button.

If I click on the edit button, the button should no longer be displayed and the save button should be displayed. I have implemented this logic. The problem is that when I click on the Edit button, it iterates through the entire list and all the buttons are changed.

However, when I click on a button, I only want the button to be changed for that element and not for the entire list. How can I make it so that it only applies to one element at a time?

const [editing, setEditing] = useState(false);
const editingTraining  = (id) => {
    console.log("Editing works")
    setEditing(!editing);
}
     {trainingData.map((d, i) => (
            <div key={i}>                
                {
                    editing === false && <button className="button is-info" onClick={() => editingTraining(d.trainingsid)}>Edit</button>
                }
                {
                    editing === true && <button className="button is-success" onClick={() => editingTraining(d.trainingsid)}>Save</button>
                }
                <br />
            </div>
        ))}

Upvotes: 0

Views: 760

Answers (2)

marius florescu
marius florescu

Reputation: 672

The problem is that when I click on the Edit button, it iterates through the entire list and all the buttons are changed.

This is not what actually happens. In your component, you have only one editing boolean that you are switching. They all use the same flag for conditional rendering.

In order to show/not show each button you could extract the button in a separate component, which has its own editing state.

Example:

const ActionButton = (props) => {
    const [editing,setEditing] = useState(false)
    
    const yourFunction = () => …

    return (
        <>
        {editing === false ? (
            <button className="button is-info" onClick={() => yourFunction()}>Edit</button>
        ) : (
            <button className="button is-info" onClick={() => yourFunction()}>Save</button>
        )}
        </>
    )
}

And then in your map function from your main component just render it + add the necessary props/functions to your ActionButton component.

Upvotes: 1

Chris
Chris

Reputation: 6631

You should store which entry you are editing. For example, by using the trainingsid property liko so:

const [editing, setEditing] = useState(null);

const editingTraining = (id) => {
  setEditing(id);
};

return (
  <div>
    {trainingData.map((d, i) => (
      <div key={i}>
        {editing === d.traningsid ? (
          <button className="button is-success" onClick={() => editingTraining(null)}>Save</button>
        ) : (
          <button className="button is-info" onClick={() => editingTraining(d.trainingsid)}>Edit</button>
        )}
        <br />
      </div>
    ))}
  </div>
);

Upvotes: 1

Related Questions