Javascript 如何初始调用api以保存帖子
我想把我的代码片段保存到商店。然而,我现在面临一些问题,我只在完成api调用后从服务器获取代码段id。所以第一次,我只需要向api调用发送snippetTile和snippetDescription。我希望snippetId检查帖子是否已经存在并更新它。当我第一次创建代码段时,如何在api/savesnippets api调用中省略代码段ID?我只希望snippetTitle和snippetDescription被发送到api调用,因为如果一切顺利,我将获得snippetId作为服务器响应。现在我的api调用的请求负载看起来像 actions.js,我在其中调用apiJavascript 如何初始调用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作为服务器响应。现在
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文件中,如果您在那里看到caseSAVE\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文件中,如果您在那里看到caseSAVE\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)
}`