Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
React-Node.js API存储调度问题:post请求需要2次尝试存储数据_Node.js_Reactjs_Express_React Redux_Axios - Fatal编程技术网

React-Node.js API存储调度问题:post请求需要2次尝试存储数据

React-Node.js API存储调度问题:post请求需要2次尝试存储数据,node.js,reactjs,express,react-redux,axios,Node.js,Reactjs,Express,React Redux,Axios,更新 即使在正确建议以非变异的方式修改setClientData reducer之后,问题仍然存在。我还向clientData添加了totalItems和totalPrice,这样orderData就可以完全被clientData替换 原始问题 我是一名编程专业的学生,作为一项作业,我需要使用React和Node.js Express Web API+MySQL(所有内容都在localhost上运行)制作一个非常简单的webshop(无身份验证或支付方法) 一切都很好,但有一个bug我无法控制

更新 即使在正确建议以非变异的方式修改setClientData reducer之后,问题仍然存在。我还向clientData添加了totalItems和totalPrice,这样orderData就可以完全被clientData替换

原始问题

我是一名编程专业的学生,作为一项作业,我需要使用React和Node.js Express Web API+MySQL(所有内容都在localhost上运行)制作一个非常简单的webshop(无身份验证或支付方法)

一切都很好,但有一个bug我无法控制。我总是需要按下“下订单按钮”两次,它才能工作

第一次单击该按钮时,会出现来自express validator的status 400响应,因为通过输入文本字段收集的客户机数据似乎为空。当您再次单击按钮时,它确实起作用。使用Postman不会出现问题,因此问题出现在React应用程序中,更具体地说,当用户数据存储在redux商店的购物车切片(cartState)中时

在Confirm.jsx中,在用户输入他/她的数据之后(以及在前端验证之后),我使用调度“setClientData”和更新cartState的数据

为了调试这个问题,我在两个不同的时刻做了一些console.log:一次在axios POST之前,一次在axios POST之后

第一次尝试时,数据似乎未成功存储在cartState中。“firstName”等是空的,我们得到400个响应。“totalPrice”和“totalItems”的值确实正确,但在上一步中已存储在cartState中)

但是,在“setClientData”调度期间,我还使用了一些console.log,然后数据似乎已经成功地存储在cartState中

在第二次尝试后,“firstName”等被成功地存储在cartState中,然后也存储在数据库中

我真的不明白这是怎么可能的,因为我相信调度是一个同步过程,所以我不认为第一个控制台。日志完成得太快了,而且我也不知道axios POST会如何影响cartState,使其第二次工作

如果您对此事有任何见解,我将不胜感激,提前谢谢您

store/cart/slice.js:

import {createSlice} from "@reduxjs/toolkit";

const cartSlice = createSlice({
    name: 'cart',
    initialState: {
        orderLines: {},
        orderData: {
            firstName: "",
            lastName: "",
            street: "",
            number: "",
            postalCode: "",
            city: "",
            telephone: "",
            email: "",
            totalPrice: 0,
            totalItems: 0
        }
    },
    reducers: {

        setClientData: (state,action) => {
            const {payload} = action;
            console.log("payloadFirstName: "+payload.firstName);
            state.orderData.firstName = payload.firstName;
            console.log("stateFirstName: "+state.orderData.firstName);
            state.orderData.lastName = payload.lastName;
            state.orderData.street = payload.street;
            state.orderData.number = payload.number;
            state.orderData.postalCode = payload.postalCode;
            state.orderData.city = payload.city;
            state.orderData.telephone = payload.telephone;
            state.orderData.email = payload.email;
        },
if (everythingFilledOutCorrectly) {

            const clientData = {
                firstName: inputFields[0].value.trim(),
                lastName: inputFields[1].value.trim(),
                street: inputFields[2].value.trim(),
                number: inputFields[3].value.trim(),
                postalCode: inputFields[4].value.trim(),
                city: inputFields[5].value.trim(),
                email: inputFields[6].value.trim(),
                telephone: inputFields[7].value.trim(),
            }
            
            store.dispatch(setClientData(clientData));
            console.log("firstName1: "+cartState.orderData.firstName);
            console.log("totalItems: "+cartState.orderData.totalItems);
            console.log("totalPrice: "+cartState.orderData.totalPrice);

            //Place order in database  
            axios.post('http://localhost:3001/order', cartState)
            .then(response => {
                
                console.log("firstName2: "+cartState.orderData.firstName);
                console.log("totalItems: "+cartState.orderData.totalItems);
                console.log("totalPrice: "+cartState.orderData.totalPrice);

                if (response.status===200) {
                    //empty cart
                    store.dispatch(emptyCart());

                    //go to confirmation page
                    history.push(`/confirmation/${response.data}`);
                }
                else alert("Something went wrong.");
            })

            
         }
确认。jsx:

import {createSlice} from "@reduxjs/toolkit";

const cartSlice = createSlice({
    name: 'cart',
    initialState: {
        orderLines: {},
        orderData: {
            firstName: "",
            lastName: "",
            street: "",
            number: "",
            postalCode: "",
            city: "",
            telephone: "",
            email: "",
            totalPrice: 0,
            totalItems: 0
        }
    },
    reducers: {

        setClientData: (state,action) => {
            const {payload} = action;
            console.log("payloadFirstName: "+payload.firstName);
            state.orderData.firstName = payload.firstName;
            console.log("stateFirstName: "+state.orderData.firstName);
            state.orderData.lastName = payload.lastName;
            state.orderData.street = payload.street;
            state.orderData.number = payload.number;
            state.orderData.postalCode = payload.postalCode;
            state.orderData.city = payload.city;
            state.orderData.telephone = payload.telephone;
            state.orderData.email = payload.email;
        },
if (everythingFilledOutCorrectly) {

            const clientData = {
                firstName: inputFields[0].value.trim(),
                lastName: inputFields[1].value.trim(),
                street: inputFields[2].value.trim(),
                number: inputFields[3].value.trim(),
                postalCode: inputFields[4].value.trim(),
                city: inputFields[5].value.trim(),
                email: inputFields[6].value.trim(),
                telephone: inputFields[7].value.trim(),
            }
            
            store.dispatch(setClientData(clientData));
            console.log("firstName1: "+cartState.orderData.firstName);
            console.log("totalItems: "+cartState.orderData.totalItems);
            console.log("totalPrice: "+cartState.orderData.totalPrice);

            //Place order in database  
            axios.post('http://localhost:3001/order', cartState)
            .then(response => {
                
                console.log("firstName2: "+cartState.orderData.firstName);
                console.log("totalItems: "+cartState.orderData.totalItems);
                console.log("totalPrice: "+cartState.orderData.totalPrice);

                if (response.status===200) {
                    //empty cart
                    store.dispatch(emptyCart());

                    //go to confirmation page
                    history.push(`/confirmation/${response.data}`);
                }
                else alert("Something went wrong.");
            })

            
         }
chrome开发者工具

还原剂不得改变初始状态:

setClientData: (state,action) => {
        const {payload} = action;
        console.log("payloadFirstName: "+payload.firstName);
        state.orderData.firstName = payload.firstName;
        console.log("stateFirstName: "+state.orderData.firstName);
        state.orderData.lastName = payload.lastName;
        state.orderData.street = payload.street;
        state.orderData.number = payload.number;
        state.orderData.postalCode = payload.postalCode;
        state.orderData.city = payload.city;
        state.orderData.telephone = payload.telephone;
        state.orderData.email = payload.email;
    },
取而代之的是这个

setClientData: (state,action) => {
        const {payload} = action;
        return { ...state, orderData: { ...payload } }
    },

在发送clientData之前,它是什么?还要注意redux reducer必须返回一个新的状态,而不是改变初始值谢谢你的回答。我照你的建议做了,但问题还是一样。