-
Notifications
You must be signed in to change notification settings - Fork 3
Tasks ‐ Front End
This is just a little page describing how the tasks are implemented on the front end.
HomePage -> TaskBox -> TaskType -> TaskCard
The tasks are in a state variable called tasks
inside the HomePage component, following the defined JSON structure. The data is passed to TaskBox for handling the display and drag-and-drop. The components TaskType and TaskCard are generated dynamically according to their names. When a change is made to a card on the front end, changes are propagated upward to TaskType via a property function called callback()
. The function of callback in TaskCard is described below. TaskType similarly accepts this change and propagates it upward to TaskBox. There is a similar callback for this purpose, but it should not need to be used for anything else at this level. At this point the setTasks
state function which was passed into TaskBox as updateTasksData
is called with the changes, then HomePage detects this page in a useEffect()
and updates the database.
So if you want to change the tasks data, pass setTasks
into your component, then call it when ready and the useEffect()
in HomePage will handle the rest.
In TaskCard, there is a function available called callback()
which takes 3 parameters: idx
, task
, and saveWorthy
. The first two parameters should always be idx
and task
because these are the index and the actual task data respectively. saveWorthy
is a boolean value for whether this specific change should trigger a database update. For the most part, it should be true.
Below is an example of how to use callback()
from within a TaskCard to update the tasks list with a change from the variable show
. At the time of writing, we have not decided on whether a task being opened or not should be saved in the database.
- Update the task
- Call the callback function with idx, the task itself, and a boolean for whether this change is save-worthy
This concept can be extended for any front-end change to a card. For example, when updating notes, the checkmark button could be used to call a function that does something similar, modifying task.notes
then executing callback()
on the updated data.
Changes made by child components are reflected in the parent if the data has the same memory address, which is true for JavaScript objects. So why is it necessary to do all this nonsense with callbacks?
React doesn't know when to render these changes unless the items are modified in a state variable.
- But we're not sending the whole variable to each component. The TaskCard only has information about its current task, and likewise the TaskType only has information about all its tasks. The TaskBox is the only component that has everything.
- And when modifying a state variable, React only does a shallow check for changes. In other words, even if we're using a state variable, and even if the variable is updated, React won't realize.
That's why we have to pass data from child to parent and instead of just updating the object, set it to a copy of itself. (That's why you will see temp_x = {...x}
or similar sometimes in the code.)
I'm not exactly sure if this is entirely true, but by testing and after many failures, it seems consistent.
Dragging is mostly handled by react-beautiful-dnd
, with a custom function for handling reordering when a card is dropped. The function removes the item from the previous array and inserts it in the new array. Use of the spread operator ...
is seen here for reasons described above.
For react-beautiful-dnd
purposes, it's crucial that all the TaskCard elements have a unique key={}
property. I was thinking of using the task name, but that might not be unique, so some sort of unique ID is required for any tasks on the same day.
This is our documentation Wiki for robustly describing elements of the project that other developers may need to interface with.