Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.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
Javascript 如何在action creator函数中更改组件的内部状态属性_Javascript_Reactjs_Redux - Fatal编程技术网

Javascript 如何在action creator函数中更改组件的内部状态属性

Javascript 如何在action creator函数中更改组件的内部状态属性,javascript,reactjs,redux,Javascript,Reactjs,Redux,我正在开发一个React应用程序,并使用Redux存储状态。我有以下代码: category-arrows.component.jsx: import React, { Component } from 'react'; import { connect } from 'react-redux'; import { increaseCategoryRank, decreaseCategoryRank, fetchCategoryRanks } from '../../redux/menu/men

我正在开发一个React应用程序,并使用Redux存储状态。我有以下代码:

category-arrows.component.jsx:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { increaseCategoryRank, decreaseCategoryRank, fetchCategoryRanks } from '../../redux/menu/menu.actions';
import './category-arrows.styles.scss';

class CategoryArrows extends Component {

    state = {
        isSending: false
    }

    render() {

        const { category } = this.props;
        const categoryClicked = true;

        return (
            <div className="arrows-container">
                <div className="up-arrow" onClick={
                    () => {
                        if(this.state.isSending === false) {
                            this.props.increaseCategoryRank(category, categoryClicked)
                        }
                        this.props.fetchCategoryRanks(this.props.menu);
                }}></div>
                <div className="category-rank">
                    <p>{category.rank}</p>
                </div>
                <div className="down-arrow" onClick={
                    () => {
                        if(this.state.isSending === false) {
                            this.props.decreaseCategoryRank(category, categoryClicked)
                        }
                        this.props.fetchCategoryRanks(this.props.menu);
                }}></div>
            </div>
        )
    }
}

const mapStateToProps = state => ({
    menu: state.menu
})

export default connect(mapStateToProps, { increaseCategoryRank, decreaseCategoryRank, fetchCategoryRanks } )(CategoryArrows);
menu.types.js:

export const INCREASE_CATEGORY_RANK = "INCREASE_CATEGORY_RANK";
export const DECREASE_CATEGORY_RANK = "DECREASE_CATEGORY_RANK";
export const FETCH_CATEGORY_RANKS = "FETCH_CATEGORY_RANKS";
menu.reducer.js:

// import INITIAL_STATE from './menu.data';
import { INCREASE_CATEGORY_RANK, DECREASE_CATEGORY_RANK, FETCH_CATEGORY_RANKS } from './menu.types';

const INITIAL_STATE = []


export default (state = INITIAL_STATE, action) => {
    switch (action.type) {

        case INCREASE_CATEGORY_RANK: {
            console.log("Went into increase category rank");

            if(action.categoryClicked === false) {
                return state;
            }

            const menuArray = [...state];

            var index = menuArray.map(category => category._id).indexOf(action.category._id);

            //if it's the first element in array it won't move up
            if(index === 0) {
                return state;
            } else {
                const temp = menuArray[index];
                menuArray[index] = menuArray[index - 1];
                menuArray[index - 1] = temp;


                var newrank = 0;

                menuArray.forEach(category => {
                     category.rank = newrank++;
                });


                return menuArray;
            }

        }
        case DECREASE_CATEGORY_RANK: {
            console.log("Went into decrease category rank");

            if(action.categoryClicked === false) {
                return state;
            }

            const menuArray = [...state];

            console.log(menuArray);

            var index = menuArray.map(category => category._id).indexOf(action.category._id);

            //if it's the last element in the array, it won't move down
            if(index === menuArray.length - 1) {
                return state;
            } else {
                const temp = menuArray[index];
                menuArray[index] = menuArray[index + 1];
                menuArray[index + 1] = temp;


                var newrank = 0;

                menuArray.forEach(category => {
                    category.rank = newrank++;
                });


                return menuArray;
            }
        }
        case FETCH_CATEGORY_RANKS:
            return state;
        default:
            return state;
    }
}
在CategoryRows组件中,我有一个名为
isSending
的状态属性,该属性设置为
false
。在我的
fetchCategoryRanks
action creator中,我使用
fetch
将状态菜单数组中的类别信息发送到服务器

我希望能够将
isSending
属性从
CategoryRows
组件设置为
true
false
,具体取决于函数
fetchCategoryRanks
中的某些条件


然而,我不知道最好的方法是什么。任何见解都将不胜感激。

第一条道路

您可以通过向axios api调用发送回调函数来更改内部状态。在axios请求启动之前,您可以从axios api函数调用该回调函数来设置
isSending=true
,在请求完成之后,再次调用回调函数来设置
isSending=false
。回调函数实现必须在调用axios api的组件中

Api调用

this.props.fetchCategoryRanks(this.props.menu, (response) => {
    if (isRequestStart) {
        this.setState({
            isSending: true
        });
    }
    if (!isRequestStart) {
        this.setState({
            isSending: false
        });
    }
});
下面是您的取回请求

export const fetchCategoryRanks = (menu, callback) => async dispatch => {
    var sentRequests = 0;
    menu.map(async (category) => {
        const menuLength = menu.length;
        callback({
            isRequestStart: true
        });
        const options = {
            ...apiConfig(),
            method: 'PUT',
            body: JSON.stringify(category)
        }
        const response = await
        fetch(`${apiUrl}/category/${category._id}`, options)
        let data = await response.json()
        if (response.ok) {
            callback({
                isRequestStart: false
            });
            console.log("It got sent")
            sentRequests++;
            console.log("Printing sentRequests");
            console.log(sentRequests);
            if (sentRequests === menuLength) {
                console.log("All the requests have been sent");
            }
        } else {
            alert(data.error);
            callback({
                isRequestStart: false
            });
        }
    });
    dispatch({
        type: FETCH_CATEGORY_RANKS,
        menu
    });
}
第二种方式


您可以使用reducer,通过从axios api调度函数,调用与上述相同的调度函数,设置
isSending
的初始状态。您可以在组件中使用该reducer状态。

有没有办法使用fetch而不是axios来实现这一点?您也可以使用上述步骤获取api。它既适用于fetch,也适用于axios
export const fetchCategoryRanks = (menu, callback) => async dispatch => {
    var sentRequests = 0;
    menu.map(async (category) => {
        const menuLength = menu.length;
        callback({
            isRequestStart: true
        });
        const options = {
            ...apiConfig(),
            method: 'PUT',
            body: JSON.stringify(category)
        }
        const response = await
        fetch(`${apiUrl}/category/${category._id}`, options)
        let data = await response.json()
        if (response.ok) {
            callback({
                isRequestStart: false
            });
            console.log("It got sent")
            sentRequests++;
            console.log("Printing sentRequests");
            console.log(sentRequests);
            if (sentRequests === menuLength) {
                console.log("All the requests have been sent");
            }
        } else {
            alert(data.error);
            callback({
                isRequestStart: false
            });
        }
    });
    dispatch({
        type: FETCH_CATEGORY_RANKS,
        menu
    });
}