DEV Community

Zahid Zia
Zahid Zia

Posted on

How to set state from components

Image description

I am a newbie in react and still struggling so developed a little task manager application and using Context API. I am unable to set state where I want to set it as a array list. Ideally it should set where I am using useQuery from "Tasks.js" component. Please advise how to maintain state with the recent array changes. Currently its rendering tasks fetched from my middleware (express.js) and mysql database and no delete functionality is working.

App.jsx

import Header from "./components/Header";
import Tasks from "./components/Tasks";
import AddTask from "./components/AddTask";
import { QueryClient, QueryClientProvider } from "react-query";
import { DataContext, DataProvider } from "./context/DataContext";
import { useContext } from "react";

function App() {
  //Initialize React Query Client
  const queryClient = new QueryClient();

  const showAddTask = useContext(DataContext);
  //const tasksLength = useContext(DataContext);

  return (
    <DataProvider>
      <div className="container">
        <QueryClientProvider client={queryClient}>
          <Header />
          {showAddTask && <AddTask />}
          <Tasks />
        </QueryClientProvider>
      </div>
    </DataProvider>
  );
}
export default App;
Enter fullscreen mode Exit fullscreen mode

DataContext.js

import { createContext, useState } from "react";
export const DataContext = createContext();

export const DataProvider = (props) => {
  //Initialize button state and set function
  const [showAddTask, setShowAddTask] = useState(false);

  //Initiliaze Tasks state and set function
  const [myTasks, setTask] = useState([]);
  const [tasksLength, setTasksLength] = useState(0);

  return (
    <DataContext.Provider
      value={{
        tskstate: tasksLength,
        settskstate: setTasksLength,
        mystate: myTasks,
        setState: setTask,
        btnaddtaskstate: showAddTask,
        setbtnState: setShowAddTask,
      }}
    >
      {props.children}
    </DataContext.Provider>
  );
};
Enter fullscreen mode Exit fullscreen mode

Header.jsx

import PropTypes from "prop-types";
import Button from "./Button";
import { DataContext } from "../context/DataContext";
import { useContext } from "react";

const Header = ({ title }) => {
  //const { mystate } = useContext(UserContext);
  const { btnaddtaskstate, showAddTask, setbtnState, setShowAddTask } =
    useContext(DataContext);

  const { mystate, setTasksState } = useContext(DataContext);

  const onToggle = () => {
    setbtnState((btnaddtaskstate) => !btnaddtaskstate);
  };
  return (
    <div>
      <header className="header">
        <h1> {title} </h1>
        <Button
          color={btnaddtaskstate ? "red" : "green"}
          text={btnaddtaskstate ? "Close" : "Add"}
          onClick={onToggle}
        />
      </header>
    </div>
  );
};

Header.defaultProps = {
  title: "Task Tracker",
};

Header.propTypes = {
  title: PropTypes.string.isRequired,
};
export default Header;
Enter fullscreen mode Exit fullscreen mode

Tasks.jsx

import { useContext, useState } from "react";
import { DataContext } from "../context/DataContext";
import Task from "./Task";
import { useQuery } from "react-query";
import { getTasks } from "../api/Tasks_Api";

const Tasks = ({ task }) => {
  //const { myTasks, setTask } = useContext(DataContext);

  const { data: mydata = [] } = useQuery("TasksData", getTasks);

  return (
    <>
      {mydata.map((item, index) => (
        <Task key={item.id} task={item} />
      ))}
    </>
  );
};

export default Tasks;
Enter fullscreen mode Exit fullscreen mode

Task.jsx

import { FaTimes } from "react-icons/fa";
import { useContext } from "react";
import { DataContext } from "../context/DataContext";

const Task = ({ task }) => {
  const { mystate, setState } = useContext(DataContext);

  //Delete Task function
  const deleteTask = (id) => {
    setState(mystate.filter((task) => task.id !== id));
  };

  //Toggle Reminder function
  const toggleReminder = (id) => {
    setState(
      mystate.map((task) =>
        task.id === id ? { ...task, reminder: !task.reminder } : task
      )
    );
  };

  return (
    <div
      className={`task ${task.reminder ? "reminder" : ""}`}
      onDoubleClick={() => toggleReminder(task.id)}
    >
      <h3>
        {task.text}{" "}
        <FaTimes
          style={{ color: "red", cursor: "pointer" }}
          onClick={() => deleteTask(task.id)}
        />
      </h3>
      <p>{task.day}</p>
    </div>
  );
};

export default Task;
Enter fullscreen mode Exit fullscreen mode

Top comments (0)