简体   繁体   中英

React.js - update data in JSON server with PATCH method with state value

for learning purposes I'm creating a CRUD todo list with React and JSON-server. I got stuck with PATCH method, as it only updates data in JSON-server on the first click. I want to update the data with the component's state value.

Service file with requests:

const serverAddress = 'http://localhost:8000';
const collection = 'todoItems';

const fetchAll = async () => {
  const response = await fetch(`${serverAddress}/${collection}`);
  const todoItems = response.json();

  return todoItems;
};

const complete = async (id) => {
const completed = {
  completed : true
}

// how to set the 'completed' value in json-server based on item's state? 

const response = await fetch(`${serverAddress}/${collection}/${id}`, {
  method: 'PATCH',
  headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    },
    body: JSON.stringify(completed ),
  });

 const data = await response.json();

 return data;
}

const TodoItemsService = {
  fetchAll,
  create,
  remove,
  complete
};

export default TodoItemsService;

Card component which holds all todo items:

const Card = () => {
const [todoItems, setTodoItems] = useState([]);

const fetchAllTodoItems = async () => {
  const fetchedTodoItems = await TodoItemsService.fetchAll();
  setTodoItems(fetchedTodoItems);
};

useEffect(() => {
  (async () => {
    fetchAllTodoItems();
  })();
}, []);

const handleComplete = async (id) => {
  await TodoItemsService.complete(id);
}

return (
  <div className='card'>
    <CardHeader />
    <AddTodoForm onAddTodoItem={handleAddTodoItem} />
    <TodoItemsContainer
      todoItems={todoItems}
      onDelete={handleDelete}
      onComplete={handleComplete}
    />
  </div>
 )
}

export default Card;

TodoItemsContainer component

const TodoItemsContainer = ({ todoItems, onDelete, onComplete }) => {

return (
  <div className='todo-items-container'>
    {todoItems.length === 0 &&
      <div className='empty'>
        <img src={NoTodoItems} alt="" />
      </div>}
    {todoItems.map(({ id, text }) => (
      <TodoItem
        key={id}
        id={id}
        text={text}
        onDelete={onDelete}
        onComplete={onComplete}
      />
    ))}
  </div>
 )
}

export default TodoItemsContainer;

TodoItem component

const TodoItem = ({ id, text, onDelete, onComplete }) => {
const [isComplete, setIsComplete] = useState(false);

const handleIsCompleteById = () => {
  onComplete(id);
  setIsComplete(!isComplete);
};

const handleDeleteTodoItemById = () => {
  onDelete(id);
};

return (
  <div className={`todo-item ${isComplete ? 'complete' : ''}`}>
    <p>{text}</p>
  <div>
     <TodoItemComplete onComplete={handleIsCompleteById}/>
     <TodoItemDelete onDelete={handleDeleteTodoItemById}/>
   </div>
  </div>
 )
}

export default TodoItem;

TodoItemComplete button component

const TodoItemComplete = ({ onComplete }) => {

return (
  <button type='button' onClick={onComplete}>
    <div className='icon'>
      {<SVGComplete />}
    </div>
  </button>
  )
}

export default TodoItemComplete;

From React perspective it works fine, it marks the item as complete based on state, but I also want to reflect todo item's status as complete in my json-server. Does anyone have any tips or can see the mistake?

Simply had to pass the state as the second param in complete service and other functions that handle complete action.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM