Node.js 如何在react中成功发布后立即加载数据,并在Reactjs上使用useEffect

Node.js 如何在react中成功发布后立即加载数据,并在Reactjs上使用useEffect,node.js,reactjs,Node.js,Reactjs,我正在开发一个Mern堆栈应用程序,它有一个事件模型,该事件有许多注释。我想要的是在成功创建评论后加载评论,但是我得到一个错误,上面写着 React Hook“useffect”在函数“onSubmit”中调用,该函数既不是React函数组件,也不是自定义React Hook函数 当我在基于类的组件中执行此操作时,这是可行的,但我将代码更改为基于函数的组件。 如何在成功创建注释后立即加载注释 这是我的密码 export default function EventAndComments(pro

我正在开发一个Mern堆栈应用程序,它有一个事件模型,该事件有许多注释。我想要的是在成功创建评论后加载评论,但是我得到一个错误,上面写着

React Hook“useffect”在函数“onSubmit”中调用,该函数既不是React函数组件,也不是自定义React Hook函数

当我在基于类的组件中执行此操作时,这是可行的,但我将代码更改为基于函数的组件。 如何在成功创建注释后立即加载注释

这是我的密码

 export default function EventAndComments(props) {
    const EventComment = (props) => (
      <CardContent>
      <Typography variant="body2" color="textSecondary" component="p">
      {props.comment.name}
      </Typography>
      <Typography variant="body2" color="textSecondary" component="p">
      {props.comment.description}
      </Typography>
     </CardContent>
   );
   
   const theme = useTheme();
   const [events, setEventData] = useState([]);
   const [comments, setCommentData] = useState([]);

   const useStyles = makeStyles((theme) => ({
     root: {
       maxWidth: 850,
     },
     media: {
       height: 0,

       paddingTop: "86%", // 16:9
       display: "flex",
       flexDirection: "column",
       alignItems: "center",
     },
     expand: {
       transform: "rotate(0deg)",
       marginLeft: "auto",
       transition: theme.transitions.create("transform", {
       duration: theme.transitions.duration.shortest,
    }),
   },
    expandOpen: {
    transform: "rotate(180deg)",
   },
   avatar: {
    backgroundColor: red[500],
  },
 }));

 const classes = useStyles();
 const [expanded, setExpanded] = React.useState(false);

 const handleExpandClick = () => {
   setExpanded(!expanded);
  };

  useEffect(() => {
    axios
    .get(
      "http://localhost:9000/events/" +
      props.match.params.id +
      "/eventcomments"
    )

    .then((response) => {
      setEventData(response.data);
    })

    .catch(function (error) {
      console.log(error);
    });
 }, []);

 useEffect(() => {
   axios
   .get(
     "http://localhost:9000/events/" +
      props.match.params.id +
      "/eventcomments"
   )

   .then((response) => {
     setCommentData(response.data.eventcomments);
   })
   .catch(function (error) {
     console.log(error);
   });
 }, []);


 const nowIso = new Date();
 const getTitle = (startDateTs, endDateTs) => {
   const now = Date.parse(nowIso);

   if (endDateTs <= now) {
    return "Started:" + " " + moment(startDateTs).format("LLLL");
   }

  if (startDateTs < now && endDateTs > now) {
    return "Live:" + " " + moment(startDateTs).format("LLLL");
  }

  return "Starting:" + " " + moment(startDateTs).format("LLLL");
};

const getEnded = (startDateTs, endDateTs) => {
  const now = Date.parse(nowIso);

  if (endDateTs <= now) {
    return "Ended:" + " " + moment(startDateTs).format("LLLL");
  }

  if (startDateTs < now && endDateTs > now) {
    return "Will End:" + " " + moment(startDateTs).format("LLLL");
  }

  return "Ends:" + " " + moment(startDateTs).format("LLLL");
};

const [eventDescription, setEventComment] = React.useState("");
const [name, setName] = React.useState("");

const handleChange = (parameter) => (event) => {
  if (parameter === "name") {
    setName(event.target.value);
   }
  if (parameter === "description") {
    setEventComment(event.target.value);
  }
};

const onSubmit = useCallback(
  (e) => {
    e && e.preventDefault();
    axios
      .post(
       "http://localhost:9000/events/" +
        props.match.params.id +
        "/eventcomment",
      { name: name, description: eventDescription }
     )
     .then(function (response) {
       setCommentData(response.data.eventcomments);
     })
     .catch(function (error) {
       console.log(error);
     });
  },
  [props.match.params.id, name, eventDescription]
 );

let eventCommentList = comments.map((comment, k) => (
  <EventComment comment={comment} key={k} />
));



  return (
<Grid
  container
  spacing={0}
  direction="column"
  alignItems="center"
  justify="center"
  style={{ minHeight: "100vh" }}
>
  <Card className={classes.root}>
    <h3
      style={{
        background: "   #800000",
        color: "white",
        textAlign: "center",
      }}
      className={classes.cardheader}
    >
      {events.title}
    </h3>
    <CardHeader
      avatar={
        <Avatar aria-label="recipe" className={classes.avatar}>
          CB
        </Avatar>
      }
      action={
        <IconButton aria-label="settings">
          <MoreVertIcon />
        </IconButton>
      }
      title={getTitle(
        Date.parse(events.startingDate),
        Date.parse(events.closingDate)
      )}
      subheader={getEnded(
        Date.parse(events.startingDate),
        Date.parse(events.closingDate)
      )}
      style={{ background: "#DCDCDC" }}
    />
    <CardMedia
      className={classes.media}
      image={events.eventImage}
      title="Paella dish"
    />
    <CardContent>
      <Typography variant="body2" color="textSecondary" component="p">
        {events.description}
      </Typography>
    </CardContent>
  </Card>
  <CardContent>{eventCommentList}</CardContent>
  <form
    className={classes.root}
    noValidate
    autoComplete="off"
    onSubmit={onSubmit}
  >
    <FormControl>
      <InputLabel htmlFor="component-simple">Name</InputLabel>
      <Input
        id="component-simple"
        value={name}
        onChange={handleChange("name")}
        label="Name"
      />
    </FormControl>

    <FormControl variant="outlined">
      <InputLabel htmlFor="component-outlined">Description</InputLabel>
      <OutlinedInput
        id="component-outlined"
        value={eventDescription}
        onChange={handleChange("description")}
        label="Description"
      />
    </FormControl>
    <input
      type="submit"
      className="btn btn-outline-warning btn-block mt-4"
    />
  </form>
 </Grid>
);
导出默认函数EventAndComments(props){
const EventComment=(道具)=>(
{props.comment.name}
{props.comment.description}
);
const theme=useTheme();
const[events,setEventData]=useState([]);
const[comments,setCommentData]=useState([]);
const useStyles=makeStyles((主题)=>({
根目录:{
最大宽度:850,
},
媒体:{
高度:0,,
paddingTop:“86%,//16:9
显示:“flex”,
flexDirection:“列”,
对齐项目:“中心”,
},
扩展:{
变换:“旋转(0度)”,
marginLeft:“自动”,
转换:theme.transitions.create(“转换”{
持续时间:theme.transitions.duration.shortest,
}),
},
expandOpen:{
变换:“旋转(180度)”,
},
化身:{
背景颜色:红色[500],
},
}));
const classes=useStyles();
const[expanded,setExpanded]=React.useState(false);
常量handleExpandClick=()=>{
setExpanded(!expanded);
};
useffect(()=>{
axios
.得到(
"http://localhost:9000/events/" +
props.match.params.id+
“/eventcomments”
)
。然后((响应)=>{
setEventData(response.data);
})
.catch(函数(错误){
console.log(错误);
});
}, []);
useffect(()=>{
axios
.得到(
"http://localhost:9000/events/" +
props.match.params.id+
“/eventcomments”
)
。然后((响应)=>{
setCommentData(response.data.eventcomments);
})
.catch(函数(错误){
console.log(错误);
});
}, []);
const nowIso=新日期();
常量getTitle=(开始日期、结束日期)=>{
const now=Date.parse(nowIso);
如果(现在结束日期){
返回“实时:”+“+时刻(开始日期)。格式(“LLLL”);
}
返回“开始:”+“+时刻(开始日期)。格式(“LLLL”);
};
const getend=(开始日期、结束日期)=>{
const now=Date.parse(nowIso);
如果(现在结束日期){
return“Will End:”+“+时刻(startDateTs).format(“LLLL”);
}
返回“结束:”+“+时刻(开始日期)。格式(“LLLL”);
};
const[eventDescription,setEventComment]=React.useState(“”);
const[name,setName]=React.useState(“”);
常量handleChange=(参数)=>(事件)=>{
如果(参数==“名称”){
setName(event.target.value);
}
如果(参数==“说明”){
setEventComment(event.target.value);
}
};
const onSubmit=useCallback(
(e) =>{
e&e.preventDefault();
axios
.邮政(
"http://localhost:9000/events/" +
props.match.params.id+
“/eventcomment”,
{name:name,description:eventDescription}
)
.然后(功能(响应){
setCommentData(response.data.eventcomments);
})
.catch(函数(错误){
console.log(错误);
});
},
[props.match.params.id、名称、事件描述]
);
让eventCommentList=comments.map((comment,k)=>(
));
返回(
{events.title}
{events.description}
{eventCommentList}
名称
描述
);
}


`您只能在顶层使用挂钩,请阅读

在您的情况下,为什么不在请求成功时更新状态

const onSubmit = (e) => {
  e.preventDefault();
  axios
    .post(
      "http://localhost:9000/events/" + props.match.params.id + "/eventcomment",
      { name: name, description: eventDescription }
    )
    .then(function (response) {
      setCommentData(response.data.eventcomments);
    })
    .catch(function (error) {
      console.log(error);
    });
};

您只能在顶层使用挂钩,请阅读

在您的情况下,为什么不在请求成功时更新状态

const onSubmit = (e) => {
  e.preventDefault();
  axios
    .post(
      "http://localhost:9000/events/" + props.match.params.id + "/eventcomment",
      { name: name, description: eventDescription }
    )
    .then(function (response) {
      setCommentData(response.data.eventcomments);
    })
    .catch(function (error) {
      console.log(error);
    });
};

@丹尼斯谢谢你,但除非我刷新页面,否则它仍然不会显示评论。不过,在完成了你说我应该做的事情之后,每当我创建新评论时,它都会删除一个空格。@丹尼斯谢谢你,但是在完成了你说我应该做的事情之后,除非我刷新页面,否则它仍然不会显示评论,每当我创建新的注释时,它都会删除一个空格。它说useCallback没有定义,所以我在React require中添加了useCallback,但出现了另一个错误,说没有定义
e
(事件)@Liuu can change
e.preventDefault()==>
e&e.preventDefault()执行此操作后,post请求停止工作,注释不会创建@如果
props.match.params.id
name
eventDescription
没有更改,则此函数将不会再次请求。所以你可以检查你的代码,或者你可以告诉我更多关于它的信息,它也会在没有我点击createit的情况下发布它说useCallback没有定义,所以我在React require中添加了useCallback,但是发生了另一个错误,说没有定义
e
(事件)@Liuu可以更改
e.preventDefault()==>
e&e.preventDefault()执行此操作后,post请求停止工作,注释不会创建@如果
props.match.params.id
name
eventDescription
没有更改,则此函数将不会再次请求。所以你可以检查你的代码,或者你可以告诉更多关于它的信息,它也可以在没有我点击创建的情况下发布自己
const [comments, setCommentData] = useState([]);

const onSubmit = useCallback(
  (e) => {
      e && e.preventDefault();
      axios
        .post(
          "http://localhost:9000/events/" +
            props.match.params.id +
            "/eventcomment",
          { name: name, description: eventDescription }
        )
        .then(function (response) {
          console.log(response);
          setCommentData(response.data.eventcomments);
        })
        .catch(function (error) {
          console.log(error);
        });
      },
    [props.match.params.id, name, eventDescription],
  )

  useEffect(()=>{
    onSubmit()
  },[onSubmit])