Javascript 在reactjs组件中触发刷新?
我在React/typescript/node中有一个简单的todo应用程序。我有以下组成部分: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
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的知识,这样你可能会发现它没有改变