首页 > 解决方案 > ReactJS:如何使用 POST 请求更新 API 中的布尔字段

问题描述

所以我基本上在做的是,我有一个调用活动的 API 和它自己的细节。

谢谢!

到目前为止,这是我的代码:

应用程序.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>
);

标签: javascriptreactjspost

解决方案


出于某种原因,我不确定为什么,但是如果您在 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


推荐阅读