javascript - 更新状态和后端
问题描述
我想知道使用我的反应应用程序执行 HTTP PUT 的最佳方法。我有一个从https://jsonplaceholder.typicode.com/posts/1Post
获取数据并显示数据的组件。
我有另一个组件EditPost
,当单击“编辑”按钮时会显示一个对话框,用户可以在其中编辑帖子。当前数据EditPost
通过道具发送到。
问题
- 是否最好将状态保持在
Post
组件中保存状态吗? - 如果是这样,是否应该将状态更新和 HTTP PUT 调用放在
Post
组件中 - 我该如何更新例如。
title
而不是 ? 的其他属性post
?
帖子组件
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import Hello from './Hello';
import axios from "axios";
function Post() {
const [post, setPost] = useState();
useEffect(() => {
const fetchData = async () => {
try {
const result = await axios(
"https://jsonplaceholder.typicode.com/posts/1"
);
setPost(result.data);
} catch (error) {console.log(error)}
};
fetchData();
}, []);
return(
<div>
<h1>{post? post.id: ""}</h1>
<h1>{post? post.title: ""}</h1>
<h1>{post? post.body: ""}</h1>
<EditPost value={post}/>
</div>)
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Post/>, rootElement);
}
编辑帖子组件:
import React from "react";
import Button from "@material-ui/core/Button";
import TextField from "@material-ui/core/TextField";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
export default function EditPost(props) {
const [open, setOpen] = React.useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
function handleSubmit() {
//Do something
}
return (
<form onSubmit={handleSubmit}>
<div>
<Button variant="outlined" color="primary" onClick={handleClickOpen}>
Update Post
</Button>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">Update Post</DialogTitle>
<DialogContent>
<DialogContentText>Update Post</DialogContentText>
<TextField
autoFocus
margin="dense"
id="title"
label="title"
value={props.value.title}
fullWidth
/>
<TextField
autoFocus
margin="dense"
id="body"
label="body"
value={props.value.body}
fullWidth
/>
<TextField
autoFocus
margin="dense"
id="id"
label="id"
value={props.value.id}
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="primary">
Cancel
</Button>
<Button color="primary" type="submit">
OK
</Button>
</DialogActions>
</Dialog>
</div>
</form>
);
}
解决方案
是的,在组件中处理表单的状态是一个很好的做法,因此您需要对代码进行少量修改。
您缺少处理要修改的值的函数,因此您可以使用服务对其进行更新,并在后端和 ui 上具有相同的状态。
- 首先你需要一个变量来存储你的
title
(和其他道具)状态,让我们用标题做一个例子。
const [title, setTitle] = useState('');
您还可以将标题设置为父组件请求的数据的道具:
const [title, setTitle] = useState(props.value.title);
- 然后你必须创建一个处理
title
状态的函数。
const handleTitle = ( e ) => {
setTitle(e.target.value);
}
- 您必须将此功能添加到您的
TextField
组件中。
<TextField
autoFocus
margin="dense"
id="title"
label="title"
value={title}
onChange={handleTitle}
fullWidth
/>
- 当您拥有处理对象道具的所有方法时,在这种情况下是 :和
title
,您将需要一个方法来将所有这些数据提交给您的服务。body
id
const handleSubmit = () => {
const newData = {title: title, id: id, body: body };
//So here you will submit your data , and when the data is successfully submited you will have to update you Parent state to have the same post data in both components, so you will have to pass your 'setPost' method to EditPost Component to be able to do this:
props.setPost(newData)
}
因此,要传递更新当前帖子的方法,您必须在EditPost
声明中执行以下操作:
<EditPost setPost={setPost} value={post}/>
推荐阅读
- javascript - 为什么 npm start 不执行?
- git - 如何通过删除合并提交使我的 Git 历史更清晰?
- sql - SQL - 出现在特定类别的所有存储桶中的项目
- powershell - 从 PowerShell 中的输出中删除空格
- ios - App Store Connect - 更改修改元数据
- sql - Oracle 11g - 计划的作业不会运行
- vue.js - 如何使用带有复选框的 Vue 计算设置器?
- java - Java单例类和多线程
- android - 如何在 Android Studio 中经常检查我的 wifi dBm 级别?
- java - 这段代码有什么问题。执行时它只显示写在 else 语句中的语句