【问题标题】:Trigger refresh in reactjs component?在reactjs组件中触发刷新?
【发布时间】:2021-02-26 09:41:00
【问题描述】:

我在 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 方法来检测列表中的更改,但它不起作用。有什么想法吗?

【问题讨论】:

  • 我认为这回答了你的问题:stackoverflow.com/questions/49378949/…
  • 我认为您有点错过了 React 中的单向数据流概念。你根本不需要关心 React 重新渲染的内容、地点和时间,相反,你应该专注于你的数据(你的状态),所以一旦它更新,React 就会完成它的工作。回到正题,您需要从您的孩子向父母发送lift state up,以便它知道发生了一些变化并需要重新渲染。

标签: javascript node.js reactjs typescript


【解决方案1】:

考虑使用 useEffect 钩子。使用这个钩子,你实际上可以说何时应该渲染组件、函数等。

更多关于它的使用信息可以在这里找到: https://reactjs.org/docs/hooks-effect.html

【讨论】:

  • 你应该抽出一些时间来复习一下useEffect()钩子的知识,这样你可能会发现它不会触发刷新(正如 OP 所要求的那样),而是在 组件重新渲染之后执行必要的副作用。
猜你喜欢
  • 2020-09-02
  • 1970-01-01
  • 2017-03-03
  • 1970-01-01
  • 2012-05-24
  • 1970-01-01
  • 2020-03-25
  • 2020-04-16
  • 1970-01-01
相关资源
最近更新 更多