我试图通过redux设置概要文件状态。但是由于某种原因,我的axios被调用了两次
我的数据库profile.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// Create Schema
const ProfileSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: "users"
},
preference: [
{
type: String
}
],
date: {
type: Date,
default: Date.now
}
});
module.exports = Profile = mongoose.model("profile", ProfileSchema);
myCreatePreferences类别
import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import checkboxes from "./checkboxes";
import Checkbox from "./Checkbox";
import axios from "axios";
import { Redirect } from "react-router";
import { withRouter } from "react-router-dom";
import Select from "react-select";
import { getCurrentProfile } from "../../actions/profileActions";
const options = [
{ value: "Guns", label: "Guns" },
{ value: "Gay Marriage", label: "Gay Marriage" },
{ value: "Abortion", label: "Abortion" },
{ value: "IT", label: "IT" }
];
class CreatePreferences extends Component {
constructor() {
super();
this.state = {
selectedOption: [],
fireRedirect: false
};
this.onSubmit = this.onSubmit.bind(this);
}
onSubmit(e) {
e.preventDefault();
let tempArray = [];
for (let i = 0; i < this.state.selectedOption.length; i++) {
tempArray[i] = this.state.selectedOption[i].value;
}
const preference = {
tempArray
};
//axios
// .post("/api/profile/", { tempArray: tempArray })
//.then(res => res.data)
// .catch(err => console.log(err));
this.props.getCurrentProfile(preference);
this.setState({ fireRedirect: true });
}
handleChange = selectedOption => {
this.setState({ selectedOption });
console.log(`Option selected:`, selectedOption);
};
render() {
const { selectedOption } = this.state;
console.log(selectedOption.value);
const { fireRedirect } = this.state;
return (
<div>
<form onSubmit={this.onSubmit}>
<Select
value={selectedOption}
isMulti
onChange={this.handleChange}
options={options}
/>
<input
type="submit"
className="btn btn-info btn-block mt-4"
value="Save Preferences"
/>
{fireRedirect && <Redirect to={"/"} />}
</form>
</div>
);
}
}
CreatePreferences.propTypes = {
profile: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
profile: state.profile
});
export default connect(
mapStateToProps,
{ getCurrentProfile }
)(withRouter(CreatePreferences));
我配置文件操作类
import axios from "axios";
import {
GET_PROFILE,
PROFILE_LOADING,
GET_ERRORS,
CLEAR_CURRENT_PROFILE
} from "./types";
//Get current profile
export const getCurrentProfile = preference => dispatch => {
dispatch(setProfileLoading());
axios
.post("/api/profile", preference)
.then(res =>
dispatch({
type: GET_PROFILE,
payload: res.data
})
)
.catch(err =>
dispatch({
type: GET_PROFILE,
payload: { err }
})
);
};
//Profile Loading
export const setProfileLoading = () => {
return {
type: PROFILE_LOADING
};
};
//Clear Profile
export const clearCurrentProfile = () => {
return {
type: CLEAR_CURRENT_PROFILE
};
};
profileReducer.js
import {
GET_PROFILE,
PROFILE_LOADING,
CLEAR_CURRENT_PROFILE
} from "../actions/types";
const initialState = {
profile: null,
profiles: null,
loading: false
};
export default function(state = initialState, action) {
switch (action.type) {
case PROFILE_LOADING:
return {
...state,
loading: true
};
case GET_PROFILE:
return {
...state,
profile: action.payload,
loading: false
};
case CLEAR_CURRENT_PROFILE:
return {
...state,
profile: null
};
default:
return state;
}
}
index.js类的redux存储。
import { combineReducers } from "redux";
import authReducer from "./authReducer";
import errorReducer from "./errorReducer";
import profileReducer from "./profileReducer";
import postReducer from "./postReducer";
export default combineReducers({
auth: authReducer,
errors: errorReducer,
profile: profileReducer,
post: postReducer
});
当我通过axios通过profileActions从createPreference类发布数据时,我得到了两个axios发布请求。它首先按照预期填充preference,但是它立即进行另一个调用,preference再次被设置为null。(调用的)console.log
preference: Array(2), _id: "5bbc73011f67820748fcd9ab", user: "5bb87db33cb39a844f0ea46a", date: "2018-10-09T09:21:05.968Z", __v: 0}
Dashboard.js:20 {preference: null, _id: "5bbc73011f67820748fcd9ab", user: "5bb87db33cb39a844f0ea46a", date: "2018-10-09T09:21:05.968Z", __v: 0}
对于如何解决这个问题有什么建议吗?
2条答案
按热度按时间hujrc8aj1#
由于我无法访问您的所有代码(也无法调试它),这里有一个更好的方法来获取数据。我已经将其结构化为与您所拥有的非常接近,如果您遵循工作示例,您应该能够消除这个问题。
我做了什么:
1.将
onSubmit={this.onSubmit}
重命名为更标准的声明性this.handleSubmit
方法1.在
handleSubmit
类方法中调用this.setState()
以删除selectedOption
值,然后在setState回调中调用getCurrentProfile(value, history)
(用您的tempArray
替换value
)1.已将您的
<input type="submit" ... />
更改为<button type="submit" ... />
1.为
axios.get(...)
调用添加了return
(我还包括了getCurrentProfile
的async/await
版本,它可能更容易理解--还用axios.get
调用替换了axios.post
调用)1.删除了
Redirect
,而是在action
创建器中放置了一个重定向为history.push('/');
(一旦成功发送请求,它将把用户重定向回“/”--如果出错,则不重定向)1.始终将redux状态保持为1:1。换句话说,如果它是数组,则保持为数组(而不是
null
),如果它是字符串,则保持为字符串(而不是number
)......以此类推。在使用PropTypes,
时,如果您不保持这种1:1模式,则应用将抛出错误。例如,您最初将profile: null
设置为,但随后又将其设置为profile: [ Object, Object, Object ... ]
。相反,它最初应该为:profile: []
.1.使用
PropTypes
时,避免使用模棱两可的型别(例如object
或array
),而是描述它们的结构。1.由于redux的性质以及组件的设置方式,您不需要分派
setProfileLoading
。您可以只更新数据,连接的React组件将更新以反映新的更改。在短时间内分别分派两个redux操作很可能导致组件闪烁(可以将其想象为在一秒钟内调用this.setState()
两次--这将导致组件闪烁)。工作示例:https://codesandbox.io/s/ovjq7k7516
选择选项.js
操作/索引.js
还原器/索引.js
vlju58qv2#
我遇到了同样的问题。显然,
React.StrictMode
导致了这个问题。你可以在index.js
中找到React.StrictMode。删除React.StrictMode
解决了这个问题。但是,我不推荐这样做。StrictMode是一个用于突出显示应用程序中潜在问题的工具。与Fragment一样,StrictMode不呈现任何可见的UI。它为其子项激活附加检查和警告。
StrictMode目前可帮助:
当您构建应用的生产版本时,
React.StrictMode
将被自动删除,因此您无需删除它。您可以在此处阅读更多关于React.StrictMode的信息!