Saving state from input

We want to save the result of the task a user entered in after clicking on the pencil icon (or clicking "+ add task", but we'll tackle that later).

To do so, we'll declare [name, setName] from a new useState call. We'll initialize that with the name prop on the Task, which we rename to defaultName in the prop declaration (name: defaultName), so that we can track name as the locally changing name state, not the default name passed in from App.js.

We declare an onChange prop on the TaskInput component set to a new function editName. This function will destructure the default input event (typically referred to as e), which is an object with attributes (e.target.value). So, destructuring directly gives us value, which we can then call our new useState setter setName(value). Now, name will automatically be set to whatever a user enters in the input.

Your mission

There is just one problem here. Tasks array is not updated in the parent component. This isn't a problem now, but if we wanted to reuse the tasks array, we would miss this update. So, let's pass this update up to App.js

Head back over to App.js and write a function editTask that takes a task that we'd like to edit in the array. Hint- we want to call setTasks to set the new array to the a mapped array with the existing value replaced with the new task. Pass onSave as a new prop to task, and set the value to the editTask function. Then, head over to Task again and use this function inside of saveEdit.

Menu
Lesson 15/20
import { useState } from "react";
import styled from "styled-components";
import Button, { IconButton } from "./Button";

const TaskName = styled.div``;

const TaskInput = styled.input``;

const TaskRow = styled.div`
  display: grid; 
  grid-template-columns: 1fr 100px; 
  gap: 5px; 
  margin: 10px 0px; 
  width: 100%;   
`;

const RowActions = styled.div`
  display: grid; 
  grid-template-columns: 1fr 1fr; 
  gap: 4px; 
`;

function Task({ id, name: defaultName, onSave }) {
  const [editing, setEditing] = useState(false);
  const [name, setName] = useState(defaultName);

  function saveEdit() {
    setEditing(!editing);
  }

  function editName({ target: { value } }) {
    setName(value);
  }

  return (
    <TaskRow>
      {editing ? (
        <TaskInput placeholder={name} autoFocus onChange={editName} />
      ) : (
        <TaskName> {name} </TaskName>
      )}
      <RowActions>
        {editing ? (
          <>
            <Button onClick={saveEdit}> Save </Button>
            <Button onClick={() => setEditing(false)}> Cancel </Button>
          </>
        ) : (
          <>
            <IconButton onClick={() => setEditing(true)}> ✏️ </IconButton>
            <IconButton> 🗑️ </IconButton>
          </>
        )}
      </RowActions>
    </TaskRow>
  );
}

export default Task;