javascript - ReactJS:如何使用 POST 请求更新 API 中的布尔字段
问题描述
所以我基本上在做的是,我有一个调用活动的 API 和它自己的细节。
我必须归档一个调用,并且在调用的 API 中,每个调用都有一个名为“is_archived”的字段
我需要能够通过单击按钮来更新 API 以存档调用。(因此,一旦单击按钮,基本上将“is_archived”的字段从“false”更改为“true”)
并且一旦该调用被存档,它就不应再呈现或显示在应用程序上。
我的代码收到“加载资源失败:服务器响应状态为 400(错误请求)”,我确定我做错了什么,我只是无法发现它。
谢谢!
到目前为止,这是我的代码:
应用程序.jsx
import React, { Component} from 'react';
import { ActivityFeed } from './components/activity-feed/activity-feed.component.jsx';
import Header from './Header.jsx';
class App extends Component {
constructor() {
super();
this.state = {
calls: [],
showMessage: false,
is_archived: false
};
}
componentDidMount() {
fetch('https://aircall-job.herokuapp.com/activities')
.then(response => response.json())
.then(activities => this.setState({ calls: activities }))
document.getElementById("reset").disabled = true;
}
handleArchive = event => {
this.setState({calls: []});
this.setState({ showMessage: true });
document.getElementById("archive").disabled = true;
document.getElementById("reset").disabled = false;
};
handleReset = event => {
this.componentDidMount();
this.setState({ showMessage: false });
document.getElementById("reset").disabled = true;
document.getElementById("archive").disabled = false;
};
render() {
const { calls, showMessage } = this.state;
console.log(calls);
return (
<div className='App'>
<Header/>
<ActivityFeed calls={calls} />
<button type="button" className="archive-btn" id="archive"
onClick={this.handleArchive}>Archive All Calls</button>
{showMessage && <p>All calls have been archived</p>}
<button type="button" className="reset-btn" id="reset"
onClick={this.handleReset}>Reset Archived Calls</button>
</div>
);
};
}
export default App;
Activity.component.jsx
import React from 'react';
import './activity-detail.styles.css';
import missed from '../../resources/images/missed.svg';
import answered from '../../resources/images/answered.svg';
import voicemail from '../../resources/images/voicemail.svg';
function formatDate(date) {
var localDate = new Date(date);
return localDate.toDateString().split(' ').slice(1).join(' ');
}
function formatTime(time) {
var localTime = new Date(time);
return localTime.toLocaleTimeString().replace(/(.*)\D\d+/, '$1');;
}
function callType(type) {
if (type === "missed") {
return <img src={missed} alt="missed" className="call-icon"/>
}
else if (type === "answered") {
return <img src= {answered} alt="answered" className="call-icon"/>
}
else
return <img src= {voicemail} alt="voicemail" className="call-icon"/>
}
function archiveCall(id) {
fetch(`https://aircall-job.herokuapp.com/activities/${id}`, {
mode: 'no-cors',
method: "POST",
headers: {
'Accept' : 'application/json',
"Content-Type": "application/json"
},
body: JSON.stringify({
is_archived: true
}),
})
}
export const Activity = props => (
<div className='activity-container'>
<p> Date {formatDate(props.call.created_at)} </p>
<p> Time {formatTime(props.call.created_at)} </p>
<p> From {props.call.from} </p>
<p> To {props.call.to} </p>
<p> Via {props.call.via} </p>
<p> Call type {callType(props.call.call_type)} </p>
<button type="button" className="archive-call" id="archive-call"
onClick={archiveCall(props.call.id)}
>Archive call</button>
</div>
);
ActivityFeed.component.jsx
import React from 'react';
import { Activity } from '../activity-detail/activity-detail.component';
import './activity-feed.styles.css';
export const ActivityFeed = props => (
<div className='activity-feed'>
{props.calls.map(calls => (
<Activity key={calls.id} call={calls}/>
))}
</div>
);
解决方案
出于某种原因,我不确定为什么,但是如果您在 fetch POST 请求中设置了 no-cors 模式,则请求中的内容类型将更改为 text/plain。
Fetch API - Content-Type 在设置为 application/json 时以 text/plain 形式发送
我可以通过在沙箱中复制您的请求、在 Chrome 的网络选项卡中右键单击您的请求并选择“复制为 cURL”来解决这个问题。然后将其导入 Postman,以便我可以复制确切的请求。在那里,我可以看到它已按预期转换为纯文本内容而不是 JSON 正文。
当然你也可以在network选项卡里面的requests中看到这些东西,但是有时候放到Postman里面会更显眼。
所以解决方案是简单地省略“no-cors”选项,您的请求在 React 中可以正常工作。
fetch(`https://aircall-job.herokuapp.com/activities/${id}`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({
is_archived: true
})
});
https://codesandbox.io/s/cranky-khayyam-qm2rz?file=/src/App.js
推荐阅读
- python - Asyncio如何每天运行一次必须完成的事情
- android - Android Studio - 自定义吐司不显示
- html - 带有来源、媒体和尺寸的 HTML5 图片
- tinymce - 如何从 TinyMCE 4 迁移到 TinyMCE 5 - Prestashop
- ruby-on-rails - 如何在 Edge Rails 上捆绑更新应用程序
- git - 我收到错误:RPC 失败;致命:远程端意外挂断在git上
- python - Scikit-image 64 位而不是 buildrozer 中的 32 位
- json - 为什么我的 AES 256 解密方法在 iOS 14 中不起作用
- android - android拖放上的getLocalData仅在真实设备上返回null
- r - hist(add = TRUE) 显示具有相似数据的不同比例