Javascript 在reactjs组件中触发刷新?

Javascript 在reactjs组件中触发刷新?,javascript,node.js,reactjs,typescript,Javascript,Node.js,Reactjs,Typescript,我在React/typescript/node中有一个简单的todo应用程序。我有以下组成部分: import * as React from "react" import {forwardRef, useCallback, useEffect} from "react" import {ITodo} from "../types/type.todo" import {deleteTodoById, getTodos, updateTo

我在React/typescript/node中有一个简单的todo应用程序。我有以下组成部分:

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*作为“React”中的React
从“react”导入{forwardRef,useCallback,useEffect}
从“./types/type.todo”导入{ITodo}
从“./api/requests”导入{deleteTodoById,gettoos,updateTodo}
从“@material ui/core”导入{TextField}
从“材料表”导入材料表,{Icons}
从“@material ui/core/Dialog”导入对话框
从“@material ui/core/DialogTitle”导入DialogTitle
从“@material ui/core/DialogContent”导入DialogContent
从“@material ui/core/DialogActions”导入DialogActions
从“@material ui/icons/Delete”导入DeleteIcon
从“@material ui/core/Button”导入按钮
从“物料ui确认”导入{useConfirm}
从“/AddTodo”导入{AddTodo}
导出默认函数ShowTodos(){
const[todos,setTodos]=React.useState([]);
const[todo,setTodo]=React.useState({
_id:“”,
姓名:“,
正文:“,
状态:false,
createdAt:“
});
const[dialogState,setDialogState]=React.useState(false);
const confirmClick=useConfirm();
常量头=[
{title:'name',field:'name'},
{title:'description',field:'text'},
{title:'created at',field:'createdAt',defaultSort:'desc'作为常量}
]
常量表图标:图标={
删除:forwardRef((道具,ref)=>)
}
const handleStateChange=useCallback(id=>
setTodos(todos.filter(todo=>todo.\u id!=id)),[todos]
)
useffect(()=>{
getTodos()
。然后({data:{todos}}:ITodo[]| any)=>{
设置todos(todos)
})
.catch((err:Error)=>console.log(err))
}, [])
const handleUpdate=(todo:ITodo)=>{
confirmClick({description:'此操作是永久性的!'})
.然后(()=>updateTodo(todo))
.catch((err:Error)=>console.log(err))
}
常量handleDelete=(id:string)=>{
deleteTodoById(id)
.catch((err:Error)=>console.log(err))
}
返回(
{
setDialogState(true);
setTodo({u id:rowData.\u id,
名称:rowData.name,
text:rowData.text,
状态:rowData.status,
createdAt:rowData.createdAt
})
}}
行动={[
{
图标:删除图标,
工具提示:“删除项目”,
onClick:(事件,行数据:ITodo)=>{
window.confirm(“您想删除”+rowData.name+“?”);
handleDelete(rowData.\u id)
}
}
]}
/>
setDialogState(假)}
aria labelledby=“表单对话框标题”
>
更新
setDialogState(false)}>
取消
{
手动更新(todo)
setDialogState(错误)
}}>
更新
);
}
该组件的子组件是要添加TODO的组件:

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

}
import*作为“React”中的React
从“@material ui/core”导入{OutlinedInput}
从“@material ui/core/Paper”导入纸张
从“./api”导入{handleSaveTodo}
从“./types/type.todo”导入{ITodo}
从“@material ui/core/styles”导入{makeStyles}”
从“@material ui/core/IconButton”导入IconButton
从“@material ui/icons/Add”导入AddIcon
从“./api/requests”导入{addTodo}
从“时刻/时刻”导入*作为时刻
类型道具={
onAdd:(id:string)=>void
}
export const AddTodo:React.FC=({onAdd}):any=>{
const useStyles=makeStyles(()=>({
输入:{
宽度:“40%”
}
}));
const classes=useStyles();
const[todo,setTodoValue]=React.useState();
常量handleChange=(事件:React.ChangeEvent)=>{
常量值=event.target.value;
setTodoValue(值);
};
const submitEvent=(事件:React.MouseEvent):void=>{
event.preventDefault()
常数newTodo:省略={
姓名:“姓名”,
正文:todo,
状态:false,
createdAt:moment().format('MMMM Do YYYY,h:mm:ss a'),
}
addTodo(新托多)
。然后(id=>onAdd(id))
};
返回(
提交事件(e)}>
);
}

添加todo时,我希望ShowTodos组件刷新。我曾尝试使用handleChange方法来检测列表中的更改,但它不起作用。有什么想法吗?

考虑使用useffect挂钩。使用这个钩子,您实际上可以说什么时候应该呈现组件、函数等

有关其用法的更多信息,请参见:
考虑使用useffect挂钩。使用这个钩子,您实际上可以说什么时候应该呈现组件、函数等

有关其用法的更多信息,请参见:

我认为这回答了您的问题:我认为您在React中忽略了单向数据流的概念。您不必担心React重新呈现的内容、位置和时间,相反,您应该关注您的数据(您的状态),因此一旦数据更新,React将完成其工作。回到这一点上,你需要从你的孩子到父母,这样他们就知道有些东西已经改变了,需要重新渲染。我想这回答了你的问题:我想你在React中有点忽略了单向数据流的概念。您不必担心React重新呈现的内容、位置和时间,相反,您应该关注您的数据(您的状态),因此一旦数据更新,React将完成其工作。回到这一点上,你需要从你的孩子到父母,这样他们就知道有些东西已经改变了,需要重新渲染。你应该抽出一些时间,复习一下你自己关于
useffect()
hook的知识,这样你可能会发现它没有改变