How to initiate a refresh in a React.js component?

I created a basic todo app using React, TypeScript, and Node. Below is the main component:

import * as React from "react"
import {forwardRef, useCallback, useEffect} from "react"
import {ITodo} from "../types/type.todo"
import {deleteTodoById, getTodos, updateTodo} from "../api/requests"
import {TextField} from "@material-ui/core"
import MaterialTable, {Icons} from "material-table"
import Dialog from "@material-ui/core/Dialog"
import DialogTitle from "@material-ui/core/DialogTitle"
import DialogContent from "@material-ui/core/DialogContent"
import DialogActions from "@material-ui/core/DialogActions"
import DeleteIcon from '@material-ui/icons/Delete'
import Button from "@material-ui/core/Button"
import {useConfirm} from "material-ui-confirm"
import {AddTodo} from "./AddTodo"

export default function ShowTodos () {

  const [todos, setTodos] = React.useState<ITodo[]>([]);

  const [todo, setTodo] = React.useState<ITodo>({
    _id: "",
    name: "",
    text: "",
    status: false,
    createdAt: ""
  });

  const [dialogState, setDialogState] = React.useState<boolean>(false);

  const confirmClick = useConfirm();

  const headers = [
    { title: 'name', field: 'name'},
    { title: 'description', field: 'text'},
    { title: 'created at', field: 'createdAt', defaultSort:"desc" as const}
  ]


  const tableIcons: Icons = {
    Delete: forwardRef((props, ref) => <DeleteIcon {...props} ref={ref} />)

  }

   const handleStateChange = useCallback( id =>
      setTodos(todos.filter(todo => todo._id != id)), [todos]
  )

  useEffect(() => {
      getTodos()
      .then(({data: {todos}}: ITodo[] | any) => {
        setTodos(todos)
      })
      .catch((err: Error) => console.log(err))
  }, [])

  const handleUpdate = (todo: ITodo) => {

    confirmClick({ description: 'This action is permanent!' })
    .then(() =>  updateTodo(todo))
    .catch((err: Error) => console.log(err))

  }

  const handleDelete = (id: string) => {
    deleteTodoById(id)
    .catch((err: Error) => console.log(err))

  }
        return (
            <>
              <AddTodo onAdd={handleStateChange} />
      <MaterialTable title="To Dos" columns={headers} data={todos}
                     icons={tableIcons}
                     options={{
                       pageSize:20,
                       sorting:true
                     }}
                     onRowClick={(event, rowData) => {

                      setDialogState(true);
                     setTodo({_id: rowData._id,
                       name: rowData.name,
                       text: rowData.text,
                       status: rowData.status,
                       createdAt: rowData.createdAt
                     })
                     }}
                     actions={[
                       {
                         icon: DeleteIcon,
                         tooltip: 'Delete Item',
                         onClick: (event, rowData: ITodo) => {
                           window.confirm("You want to delete " + rowData.name + "?");
                           handleDelete(rowData._id)

                         }
                       }
                     ]}
      />

  <Dialog
      open={dialogState}
      onClose={() => setDialogState(false)}
      aria-labelledby="form-dialog-title"
  >
    <DialogTitle id="form-dialog-title">Update</DialogTitle>
    <DialogContent>
      <TextField
          defaultValue={todo.text}
          autoFocus
          margin="dense"
          id="name"
          fullWidth
      />
    </DialogContent>
    <DialogActions>
      <Button color="primary" onClick={() => setDialogState(false)}>
        Cancel
      </Button>
      <Button color="primary" onClick={() => {
        handleUpdate(todo)
        setDialogState(false)
      }}>
        Update
      </Button>
    </DialogActions>
  </Dialog>
</>
  );

}

As part of this component, there is a child component for adding todos:

import * as React from "react"
import {OutlinedInput} from "@material-ui/core"
import Paper from "@material-ui/core/Paper"
import {handleSaveTodo} from "../api"
import {ITodo} from "../types/type.todo"
import {makeStyles} from "@material-ui/core/styles"
import IconButton from "@material-ui/core/IconButton"
import AddIcon from '@material-ui/icons/Add'
import {addTodo} from "../api/requests"
import * as moment from "moment/moment"



type Props =  {
  onAdd: (id: string) => void
}

export const AddTodo: React.FC<Props> = ({onAdd}): any => {

  const useStyles = makeStyles(() => ({

    input: {
      width: '40%'
    }

  }));

  const classes = useStyles();

  const [todo, setTodoValue] = React.useState<string>();


  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const value = event.target.value;
    setTodoValue(value);
  };


  const submitEvent = (event: React.MouseEvent<HTMLButtonElement>): void => {
    event.preventDefault()

    const newTodo: Omit<ITodo, '_id'> = {
      name: "name",
      text: todo,
      status: false,
      createdAt: moment().format('MMMM Do YYYY, h:mm:ss a'),
    }
    addTodo(newTodo)
    .then(id => onAdd(id))
  };


    return (
        <div>
        <Paper>
          <form>
            <OutlinedInput id="component-outlined" value={todo || ''} onChange={handleChange} label="ToDo" className={classes.input}/>
            <IconButton edge="end" aria-label="add" onClick={e => submitEvent(e)}>
              <AddIcon />
            </IconButton>
          </form>
        </Paper>
        </div>
    );

}

After adding a todo, I want the ShowTodos component to refresh. I've attempted to use the handleChange method to detect changes in the list but without success. Any suggestions?

Answer №1

One useful approach is to utilize the useEffect hook. By integrating this hook into your code, you can specify when a component or function should be rendered.

For further details on how to use this hook effectively, please visit: https://reactjs.org/docs/hooks-effect.html

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to modify an object similar to manipulating an array collection

Hey there, I've heard that iterating and editing objects (not arrays) is not the best practice. Is there a more efficient way to do it as easily as it can be done with an array of objects? Check out this link for reference new Vue({ el: '#app ...

Using AngularJS to show content based on a callback function

I'm a beginner in angular and it seems like I might be overlooking something. For the registration form, I need users to provide their location. Depending on whether they allow/support navigator.geolocation, I want to display a drop-down menu for cho ...

Creating a stationary div element solely with Javascript, excluding the use of CSS, jQuery, and HTML

I've been searching all day for a solution to this issue without any success. I apologize if I overlooked any relevant posts on the topic. Currently, I am working with Qualtrics and attempting to implement a textbox with scrolling instructions that fo ...

What is the best way to consistently display a scroll bar at the bottom?

How can I ensure that the scroll bar is always at the bottom when loading pages? I need an immediate solution. The JavaScript code seems to be malfunctioning. Please assist me in resolving this issue. #student_name{ height:315px; } <div id ...

Obtaining Input Field Value in Angular Using Code

How can I pass input values to a function in order to trigger an alert? Check out the HTML code below: <div class="container p-5 "> <input #titleInput *ngIf="isClicked" type="text" class="col-4"><br& ...

Issue with VueJS where changes made to properties in the mounted hook do not properly trigger the

I'm working on a VueJS component that features a button with computed properties for its class and text. These properties change every time the button is clicked, updating smoothly with each interaction. However, I've encountered an issue when at ...

Injecting universal data into ValidationErrors in Angular

Trying to bind a value into ValidationErrors. Having this method: isUniqueEmail(control: FormControl): ValidationErrors { if (control.value != null) { console.log(control.value) if(control.value == this.foundEmail){ console ...

Transmitting JSON data object

Sending a JSON Object to JSP Page After following the provided link, I discovered that one of the answers suggests creating a JSON object using the following constructor: JSONObject jsonObj=new JSONObject(String_to_Be_Parsed); Upon downloading the JSON ...

React's constructor being invoked twice

As a newcomer to react, I am in the process of developing a simple web application but encountering an issue. It seems like my Constructor is being called twice when I load a class component. Can anyone provide some assistance? Home.js import React from ...

The sorting of objects by Lodash is not accurate

My aim is to arrange objects based on a specific property (price). var arr = [{ name: 'Apple', price: '1.03' }, { name: 'Cherry', price: '0.33' }, { name: &apo ...

In what ways can the Material-UI theme be customized to modify the font size of labels for TextFields, Menu dropdowns, and Autocomplete components within a React application?

Currently, I am in the midst of a React project and using Material-UI to style my components. My goal is to modify the theme by adjusting the font size of certain labels such as Text Field labels, Menu dropdown labels, and Autocomplete labels. Despite my ...

Exploring the Possibilities of WebAudio API through Asynchronous Events

Is there a way to trigger events after an oscillator finishes playing using the webaudio API? I am attempting to update my Vue component reactively to display data in the DOM while a note is being played. Here's a snippet of my code: <template> ...

The error message "TypeError: BrowserWindow does not function as a constructor"

const Window = require('electron') const newWindow = new Window({ width: 800, height: 600 }) Upon running these simple lines of code, I encounter an error stating: TypeError: Window is not a constructor ...

Receive live feedback from shell_exec command as it runs

I have been working on a PHP-scripted web page that takes the filename of a previously uploaded JFFS2 image on the server. The goal is to flash a partition with this image and display the results. Previously, I had used the following code: $tmp = shell_ex ...

How to retrieve an array value within a function in AngularJS

<select class="form-control" id="column" ng-model="selectedcolumn" ng-options="column for column in columns"></select> <input type="text" ng-model="test[selectedcolumn]" ng-change="search()" /> Is there a way to retrieve the value o ...

Disable the outer div scrolling in VueJS, but re-enable it once the inner div has reached the bottom of

I am currently working on a webpage that contains multiple divs stacked vertically. Here is the concept I am working with: Once the scrollbar reaches the bottom of the first div, the outer scrollbar will be disabled and the inner scrollbar will be enabled ...

I am receiving all NFT IDs when I should only be getting the ones that are associated with the current account

I am facing an issue where I am receiving all NFTs token IDs instead of just the one that belongs to the current account. The code snippet causing this problem is as follows: const { enableWeb3, account, isWeb3Enabled, Moralis, deactivateWeb3 } = useMorali ...

Issue with the navbar toggler not displaying the list items

When the screen is minimized, the toggle button appears. However, clicking it does not reveal the contents of the navbar on a small screen. I have tried loading jQuery before the bootstrap JS file as suggested by many, but it still doesn't work. Can s ...

Canvas not displaying image in JavaScript

I have a bird object with a draw function defined, but for some reason, the image is not showing up when called in the render function. Can someone please help me figure out what I'm doing wrong? Thanks in advance. EDIT: Upon further investigation, I ...

Challenges with date formatting arise for Spanish speakers when the date returns as NaN or an Invalid

I have been working on an Angular app Objective: My aim is to allow users to input dates in Spanish format (DD/MM/YYYY) and display them as such, while converting them back to English format when saving the data to the Database. Issue: One problem I enco ...