ReactJS:如何使用 POST 请求更新 API 中的布尔字段
ReactJS: How to update a boolean field in an API using a POST request
所以我基本上做的是,我有一个 API 的呼叫活动及其自己的详细信息。
我必须存档一个呼叫,在 API 个呼叫中,每个呼叫都有一个名为“is_archived”的字段“=15=]
我需要能够通过单击按钮来更新 API 以存档呼叫。 (所以基本上是在单击按钮后将“is_archived”的字段从“false”更改为“true”)
一旦该调用被存档,它就不应再呈现或显示在应用程序上。
我的代码收到“无法加载资源:服务器响应状态为 400(错误请求)”,我确定我做错了什么,我就是看不出来。
谢谢!
到目前为止,这是我的代码:
App.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+/, '');;
}
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 is sent as text/plain when it's set to application/json
我可以通过在沙箱中复制您的请求、在 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
所以我基本上做的是,我有一个 API 的呼叫活动及其自己的详细信息。
我必须存档一个呼叫,在 API 个呼叫中,每个呼叫都有一个名为“is_archived”的字段“=15=]
我需要能够通过单击按钮来更新 API 以存档呼叫。 (所以基本上是在单击按钮后将“is_archived”的字段从“false”更改为“true”)
一旦该调用被存档,它就不应再呈现或显示在应用程序上。
我的代码收到“无法加载资源:服务器响应状态为 400(错误请求)”,我确定我做错了什么,我就是看不出来。
谢谢!
到目前为止,这是我的代码:
App.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+/, '');;
}
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 is sent as text/plain when it's set to application/json
我可以通过在沙箱中复制您的请求、在 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