3
\$\begingroup\$

I've developed a goal tracking app in React.

I'm curious whether writing filter functions without using useState is appropriate or not.

Any feedback to optimize the code would be greatly appreciated.

import React, { useState, useEffect } from "react";
import GoalForm from "./Components/GoalForm";
import Header from "./Components/Header";
import Inprogress from "./Components/Inprogress";
import Completed from "./Components/Completed";

function App() {
  const [goals, setGoals] = useState(
    JSON.parse(localStorage.getItem("goals")) || []
  );
  const [editingGoal, setEditingGoal] = useState("");

  // Update local storage whenever goals change
  useEffect(() => {
    localStorage.setItem("goals", JSON.stringify(goals));
    console.log(goals);
  }, [goals]);

  const addGoal = (newGoal) => {
    if (editingGoal) {
      setGoals(
        goals.map((goal) => (goal.id === editingGoal.id ? newGoal : goal))
      );
      setEditingGoal("");
    } else {
      setGoals((goals) => [...goals, newGoal]);
    }
  };
  const editGoal = (goalEl) => {
    setEditingGoal(goalEl);
  };
  const changeStatus = (id) => {
    setGoals((goals) => {
      return goals.map((goal) =>
        goal.id === id ? { ...goal, completed: !goal.completed } : goal
      );
    });
  };
  return (
    <div className="App">
      <Header />
      <GoalForm onAdd={addGoal} editingGoal={editingGoal} />
      <div className="goal-list">
        <Inprogress
          goals={goals}
          ongoalEdit={editGoal}
          setGoals={setGoals}
          changeStatus={changeStatus}
        />
        <Completed goals={goals} changeStatus={changeStatus} />
      </div>
    </div>
  );
}

export default App;

const Completed = ({ goals }) => {
  
  const completedGoals = goals.filter((goal) => goal.completed);
import React from "react";

const Completed = ({ goals }) => {
  
  const completedGoals = goals.filter((goal) => goal.completed);

  return (
    <>
      <div className="completed-container">
        <h1 className="completed-heading">Completed</h1>
        <ul>
          {completedGoals.map((goal) => (
            <li key={goal.id} className="goal-name">
              <p>✔ {goal.goal}</p>
            </li>
          ))}
        </ul>
      </div>
    </>
  );
};
export default Completed;

const Inprogress = ({ goals, ongoalEdit, setGoals, changeStatus }) => {
  const deleteGoal = (goalEl) => {
    setGoals(goals.filter((goal) => goal.id !== goalEl.id));
  };
  const inProgressGoals = goals.filter((goal) => !goal.completed);
import React from "react";
import { FaEdit } from "react-icons/fa";
import { MdDelete } from "react-icons/md";
const Inprogress = ({ goals, ongoalEdit, setGoals, changeStatus }) => {
  const deleteGoal = (goalEl) => {
    setGoals(goals.filter((goal) => goal.id !== goalEl.id));
  };
  const inProgressGoals = goals.filter((goal) => !goal.completed);
  return (
    <>
      <div className="progress-container">
        <h1 className="progress-heading"> In progress</h1>
        <ul>
          {inProgressGoals?.map((goalEl) => (
            <li key={goalEl.id} className="goal-name">
              <input
                type="checkbox"
                checked={goalEl.completed}
                onChange={() => changeStatus(goalEl.id)}
              />

              <p>{goalEl.goal}</p>
              <div className="btn-container">
                <button
                  className="edit-btn btn"
                  onClick={() => ongoalEdit(goalEl)}
                >
                  <FaEdit />
                </button>
                <button
                  className="del-btn btn"
                  onClick={() => deleteGoal(goalEl)}
                >
                  <MdDelete />
                </button>
              </div>
            </li>
          ))}
        </ul>
      </div>
    </>
  );
};
export default Inprogress;

full code: https://github.com/devio012/goal-tracker

New contributor
dev01295 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$
0

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.