[英]How to change the internal state property of a component in an action creator function
I am working on a React application and I am using Redux to store the state.我正在开发一个 React 应用程序,我正在使用 Redux 来存储 state。 I have the following code:
我有以下代码:
category-arrows.component.jsx:类别箭头.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.actions.js: menu.actions.js:
import { apiUrl, apiConfig } from '../../util/api';
import { INCREASE_CATEGORY_RANK, DECREASE_CATEGORY_RANK, FETCH_CATEGORY_RANKS } from './menu.types';
export const decreaseCategoryRank = (category, categoryClicked) => dispatch => {
dispatch({ type: DECREASE_CATEGORY_RANK, category, categoryClicked })
}
export const increaseCategoryRank = (category, categoryClicked) => dispatch => {
dispatch({ type: INCREASE_CATEGORY_RANK, category, categoryClicked })
}
export const fetchCategoryRanks = menu => async dispatch => {
console.log("Printing menu (fetch category ranks)");
console.log(menu);
var sentRequests = 0;
menu.map(async (category) => {
const menuLength = menu.length;
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) {
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)
}
});
dispatch({ type: FETCH_CATEGORY_RANKS, menu });
}
menu.types.js: 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: 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;
}
}
In my CategoryArrows component I have a state property called isSending
which is set to false
.在我的 CategoryArrows 组件中,我有一个名为
isSending
的 state 属性,该属性设置为false
。 In my fetchCategoryRanks
action creator, I am sending information about categories from the menu array in the state to a server using fetch
.在我的
fetchCategoryRanks
动作创建器中,我使用fetch
从 state 中的菜单数组向服务器发送有关类别的信息。
I would like to be able to set the isSending
property from the CategoryArrows
component to true
or false
, depending on certain conditions in the function fetchCategoryRanks
.我希望能够将
CategoryArrows
组件中的isSending
属性设置为true
或false
,具体取决于 function fetchCategoryRanks
中的某些条件。
However, I am not sure what the best way to do this is.但是,我不确定最好的方法是什么。 Any insights are appreciated.
任何见解都值得赞赏。
First way第一种方式
You can change internal state by sending a callback function to your axios api call.您可以通过将回调 function 发送到您的 axios Z8A5DA52ED120577D359E 调用来更改内部 state。 Before the axios request starts you can call that callback function from axios api function to set
isSending=true
and after request completed again call callback function to set isSending=false
. Before the axios request starts you can call that callback function from axios api function to set
isSending=true
and after request completed again call callback function to set isSending=false
. Callback function implementation must be in component from where you are calling axios api.回调 function 实现必须在您调用 axios api 的组件中。
Api call Api 来电
this.props.fetchCategoryRanks(this.props.menu, (response) => {
if (isRequestStart) {
this.setState({
isSending: true
});
}
if (!isRequestStart) {
this.setState({
isSending: false
});
}
});
Below is your fetch request以下是您的获取请求
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
});
}
Second way第二种方式
You can use a reducer where you can set initial state of isSending
by dispatching a function from the axios api, calling the dispatch function same as above. You can use a reducer where you can set initial state of
isSending
by dispatching a function from the axios api, calling the dispatch function same as above. And you can use that reducer state into your component.您可以将减速器 state 用于您的组件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.