Javascript 如何初始调用api以保存帖子

Javascript 如何初始调用api以保存帖子,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我想把我的代码片段保存到商店。然而,我现在面临一些问题,我只在完成api调用后从服务器获取代码段id。所以第一次,我只需要向api调用发送snippetTile和snippetDescription。我希望snippetId检查帖子是否已经存在并更新它。当我第一次创建代码段时,如何在api/savesnippets api调用中省略代码段ID?我只希望snippetTitle和snippetDescription被发送到api调用,因为如果一切顺利,我将获得snippetId作为服务器响应。现在

我想把我的代码片段保存到商店。然而,我现在面临一些问题,我只在完成api调用后从服务器获取代码段id。所以第一次,我只需要向api调用发送snippetTile和snippetDescription。我希望snippetId检查帖子是否已经存在并更新它。当我第一次创建代码段时,如何在api/savesnippets api调用中省略代码段ID?我只希望snippetTitle和snippetDescription被发送到api调用,因为如果一切顺利,我将获得snippetId作为服务器响应。现在我的api调用的请求负载看起来像

actions.js,我在其中调用api

import { SAVE_POST, UPDATE_POST, RETRIEVE_POST, HOME_LOADED } from "./types";
import axios from "axios";
export const savePost = ({
  snippetId,
  snippetDescription,
  snippetTitle
}) => async dispatch => {
  const config = {
    headers: {
      "Content-Type": "application/json"
    }
  };
  let snippetData = { snippetId, snippetDescription, snippetTitle };
  try {
    if (snippetId == null) {
      const res = await axios.post(
        "/api/save",
        JSON.stringify(snippetData),
        config
      );
      snippetData.snippetId = res.data;  //cause I only get snippetId from the server
      dispatch({
        type: SAVE_POST,
        payload: snippetData
      });
    } else {
      await axios.post("/api/update", JSON.stringify(snippetData), config);
      dispatch({
        type: UPDATE_POST,
        payload: snippetData
      });
    }
  } catch (err) {
    console.log(err);
  }
};

editor.js

import React, { Component } from "react";
import { connect } from "react-redux";
import { savePost, retrievePost } from "./actions/posts";

class Editor extends Component {
  constructor(props) {
    super(props);

    this.state = {
      title: "",
      enteredText: ""
    };
  }
  componentDidMount() {
    //Load the snippet
    retrievePost(this.props.match.params.snippetId);
  }

  // Save Snippet
  performSave = snippets => {
    console.log("save function clicked");
    const { enteredText, title } = this.state;
    this.props.savePost({
      snippetId: this.props.match.params.snippetId, //this should be null when initially I'm creating a new post
      snippetDescription: enteredText,
      snippetTitle: title
    });
  };
  render() {
    return (
      <>
        <input
          type="text"
          id="titletext"
          placeholder="Enter title here"
          limit-to="64"
          className="inptxt"
          onChange={title => this.setState({ title })}
        />
        <button className="btn savebtn" onClick={this.performSave}>
          Save Snippet
          <i className="fas fa-save" />
        </button>

        <textarea
          name="enteredText"
          onChange={enteredText => this.setState({ enteredText })}
        />
      </>
    );
  }
}

const mapStateToProps = state => ({
  snippets: state.snippets
});

export default connect(
  mapStateToProps,
  { savePost, retrievePost }
)(Editor);

store.js

import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import posts from "./reducers/posts";

export const initialState = {
  snippets: [
    {
      snippetId: "1",
      snippetTitle: "test",
      snippetDescription: "test test"
    },
    {
      snippetId: "2",
      snippetTitle: "post2",
      snippetDescription: "post 2 post2"
    }
  ]
};
const store = createStore(posts, applyMiddleware(thunk));
export default store;


更新Action.js

import { SAVE_POST, UPDATE_POST, RETRIEVE_POST, HOME_LOADED } from "./types";
import axios from "axios";
export const savePost = ({
  snippetId,
  snippetDescription,
  snippetTitle
}) => async dispatch => {
const config = {
headers: {
  "Content-Type": "application/json"
}
};

// remove snippetId here --------------------------------------
    let snippetData = { snippetDescription, snippetTitle };
// --------------------------------------

try {
 if (snippetId == null) {
  const res = await axios.post(
    "/api/save",
    JSON.stringify(snippetData),
    config
  );
  snippetData.snippetId = res.data;  //cause I only get snippetId from the server
  dispatch({
    type: SAVE_POST,
    payload: snippetData
  });
} else {

//add snippetId here for update use only --------------------------------------
  await axios.post("/api/update", JSON.stringify({...snippetData, snippetId}), config); 
// --------------------------------------
  dispatch({
    type: UPDATE_POST,
    payload: snippetData
  });
}
} catch (err) {
  console.log(err);
  }
};

更新Action.js

import { SAVE_POST, UPDATE_POST, RETRIEVE_POST, HOME_LOADED } from "./types";
import axios from "axios";
export const savePost = ({
  snippetId,
  snippetDescription,
  snippetTitle
}) => async dispatch => {
const config = {
headers: {
  "Content-Type": "application/json"
}
};

// remove snippetId here --------------------------------------
    let snippetData = { snippetDescription, snippetTitle };
// --------------------------------------

try {
 if (snippetId == null) {
  const res = await axios.post(
    "/api/save",
    JSON.stringify(snippetData),
    config
  );
  snippetData.snippetId = res.data;  //cause I only get snippetId from the server
  dispatch({
    type: SAVE_POST,
    payload: snippetData
  });
} else {

//add snippetId here for update use only --------------------------------------
  await axios.post("/api/update", JSON.stringify({...snippetData, snippetId}), config); 
// --------------------------------------
  dispatch({
    type: UPDATE_POST,
    payload: snippetData
  });
}
} catch (err) {
  console.log(err);
  }
};


谢谢此外,我还需要将snippetId作为有效负载发送到reducer,或者在reducer中,只有snippetTitle和snippetDescription会正确保存,因为我只发送snippetData,因为有效负载和snippetId不包括在其中?还有
snippetData.snippetId=res.data
将未定义。如何将从服务器接收的id分配给snippetId?如果
res.data
包含该id,则没有理由
snippetData.snippetId=res.data
返回未定义的id。仔细检查您的api响应。否则您可以执行此操作。
payload:{…snippetData,res.data}
payload:{…snippetData,res.data}
没有问题。但是在reducer文件中,如果您在那里看到case
SAVE\u POST
,那么如何在snippets数组中的单个对象中存储整个POST,包括snippetId、snippetTitle、snippetDescription?我只是有点困惑这就是为什么我要问。请帮我把肉汤拿出来。此外,我还需要将snippetId作为有效负载发送到reducer,或者在reducer中,只有snippetTitle和snippetDescription会正确保存,因为我只发送snippetData,因为有效负载和snippetId不包括在其中?还有
snippetData.snippetId=res.data
将未定义。如何将从服务器接收的id分配给snippetId?如果
res.data
包含该id,则没有理由
snippetData.snippetId=res.data
返回未定义的id。仔细检查您的api响应。否则您可以执行此操作。
payload:{…snippetData,res.data}
payload:{…snippetData,res.data}
没有问题。但是在reducer文件中,如果您在那里看到case
SAVE\u POST
,那么如何在snippets数组中的单个对象中存储整个POST,包括snippetId、snippetTitle、snippetDescription?我只是有点困惑这就是为什么我要问。请帮我浏览一下,我要在这里添加代码的上述部分吗?在reducer文件中?我的代码沙盒,你能准确地显示你将把上面的代码放在哪里吗?另外,我还有一个问题,在保存帖子之后,我从服务器获取snippetId,它应该在第一次保存后立即出现在url中,比如
http://localhost:8000/editor/123
或者,如果我再次单击“保存”按钮,它会用新id保存一份副本。但我不希望这样。我希望url立即更新,这样当我再次单击“保存”按钮时,它会更新帖子,而不是添加重复的副本。如果您希望以相同的形式处理保存和编辑,您必须选择。第一个是检查当前代码段是否有
id
,如果是,那么它是一个更新,否则它是一个帖子。第二种方法是使用状态控制它是post还是put(例如:requestType=“edit”| |“add”)。检查代码中的post.js Sandboxyeah我想使用第一种方法。我想检查url中是否有任何id,这就是我在performSave函数中使用
match.params.snippetId
的原因。SAVE_POST和UPDATE_POST案例都在操作文件中。但是,我不知道如何在第一次保存帖子后立即更新
match.params.snippetId
,这就是为什么如果我再次单击“保存”按钮,它会保存另一篇新帖子,这是一个重复的副本,而不是更新已经存在的帖子。这里是您不必从url获取id的原因,只需使用snippet对象的id即可。react路由器在导航方面很有帮助,用户可以知道自己在哪里。您使用axios发送请求,因此您只需在axios url中添加id即可更新SNNIPET。我在哪里添加上述代码部分?在reducer文件中?我的代码沙盒,你能准确地显示你将把上面的代码放在哪里吗?另外,我还有一个问题,在保存帖子之后,我从服务器获取snippetId,它应该在第一次保存后立即出现在url中,比如
http://localhost:8000/editor/123
或者,如果我再次单击“保存”按钮,它会用新id保存一份副本。但我不希望这样。我希望url立即更新,这样当我再次单击“保存”按钮时,它会更新帖子,而不是添加重复的副本。如果您希望以相同的形式处理保存和编辑,您必须选择。第一个是检查当前代码段是否有
id
,如果是,那么它是一个更新,否则它是一个帖子。第二种方法是使用状态控制它是post还是put(例如:requestType=“edit”| |“add”)。检查代码中的post.js Sandboxyeah我想使用第一种方法。我想检查url中是否有任何id,这就是我在performSave函数中使用
match.params.snippetId
的原因。SAVE_POST和UPDATE_POST案例都在操作文件中。但是,我不知道如何在第一次保存文章后立即更新
match.params.snippetId
,这就是为什么如果我再次单击“保存”按钮,它会保存另一篇新文章,这是一个重复的副本,而不是更新已经存在的副本。这里是您不必从
// consider splitting your code with functions
const addToState = (state, action) => {
const cloneSnippets = JSON.stringify(JSON.parse(state.snippets)) // for deep copy
cloneSnippets.push(action.payload) // payload contains all the snipets info (id, descrip.., )
  return {
    ...state,
    snippets : cloneSnippets
  }
}

case SAVE_POST:
   return addToState(state, action)
}`