簡體   English   中英

在 reactjs 組件中觸發刷新?

[英]Trigger refresh in reactjs component?

我在 React/typescript/node 中有一個簡單的待辦事項應用程序。 我有以下組件:

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>
</>
  );

}

它有一個子組件作為添加待辦事項的組件:

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>
    );

}

添加待辦事項后,我希望刷新 ShowTodos 組件。 我試過使用 handleChange 方法來檢測列表中的更改,但它不起作用。 有任何想法嗎?

考慮使用useEffect掛鈎。 使用這個鈎子,你實際上可以說什么時候應該渲染一個組件,function 等等。

有關它的用法的更多信息可以在這里找到: https://reactjs.org/docs/hooks-effect.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM