Я новичок, чтобы реагировать на родных. Я столкнулся с какой-то странной проблемой с 3 дней.
У меня есть компонент, который имеет подкомпоненты (3 подкомпонента). Я переключаюсь между подкомпонентами с помощью элемента ButtonGroup из response-native-elements
когда я выбираю данные из API, первый раз, когда мой подкомпонент 1 загружается нормально с ожидаемыми данными, но когда я переключаюсь на подкомпонент 2 (или подкомпонент 3) и снова возвращаюсь к подкомпоненту 1, родительский компонент, который подключен к хранилищу, обновляется различными значениями данных, которые передаются каждому подкомпоненту. Я не знаю почему. Может быть, я что-то упустил или я делал глупости с 3-х дней.
Вот мой код.
- Родительский компонент: PurchaseMonth
import React, { Component, Fragment } from 'react';
import { StyleSheet, ScrollView, View } from 'react-native';
import MainView from '../../../core/layout/MainView';
import { ButtonGroup, Text, Icon } from 'react-native-elements';
import PurchaseMonthTable from './PurchaseMonthTable';
import PurchaseMonthChart from './PurchaseMonthChart';
import PurchaseMonthDetails from './PurchaseMonthDetails';
import MainHeader from '../../../core/layout/MainHeader';
import { getMonthPurchases } from '../actions/actions';
import Spinner from '../../../core/layout/Spinner';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
const tableHead = ['JOUR', 'B1', 'B2', 'B3', 'B4'];
class PurchaseMonth extends Component {
constructor(props) {
super(props);
this.state = {
selectedIndex: 0
};
}
componentDidMount() {
const { getMonthPurchases, profile } = this.props;
getMonthPurchases(profile.numero, profile.password);
}
_updateIndex = (selectedIndex) => {
this.setState({selectedIndex});
}
tableLabel = () => {
const { selectedIndex } = this.state;
const color = selectedIndex === 0 ? 'white' : '#00151C';
return (
<View>
<Icon type="font-awesome" name="table" iconStyle={{color: color}} />
<Text style={{color: color}}>Tableau</Text>
</View>
);
}
chartLabel = () => {
const { selectedIndex } = this.state;
const color = selectedIndex === 1 ? 'white' : '#00151C';
return (
<View>
<Icon type="font-awesome" name="line-chart" iconStyle={{color: color}} />
<Text style={{color: color}}>Graphe</Text>
</View>
);
}
detailsLabel = () => {
const { selectedIndex } = this.state;
const color = selectedIndex === 2 ? 'white' : '#00151C';
return (
<View>
<Icon type="font-awesome" name="info-circle" iconStyle={{color: color}} />
<Text style={{color: color}}>
Détails par produit
</Text>
</View>
);
}
render() {
const { navigation, purchases, isLoading } = this.props;
const { selectedIndex } = this.state;
const buttons = [
{ element: this.tableLabel },
{ element: this.chartLabel },
{ element: this.detailsLabel }
]; console.log("Data : " + JSON.stringify(purchases));
return (
<MainView
backgroundImageUri={require('../../../assets/images/background_no_line.png')}>
<MainHeader
title="historique des achats du mois"
uri={require('../../../assets/images/purchase.png')}
navigation={navigation}
containerStyle={{marginTop: '7%'}}
/>
{isLoading ?
<Spinner containerStyle={{marginTop: 150, alignItems: 'center'}}
color="blue" /> :
<Fragment>
<ScrollView style={styles.contentContainerStyle}>
{
selectedIndex === 0 ?
<PurchaseMonthTable head={tableHead} purchases={purchases} /> :
selectedIndex === 1 ?
<PurchaseMonthChart purchases={purchases} /> :
<PurchaseMonthDetails />
}
</ScrollView>
<ButtonGroup
onPress={this._updateIndex}
buttons={buttons}
buttonStyle={{marginHorizontal: 0}}
selectedButtonStyle={{backgroundColor: '#7B7C9E'}}
selectedIndex={selectedIndex}
containerStyle={styles.tabButtonContainerStyle}
/>
</Fragment>
}
</MainView>
);
}
}
const styles = StyleSheet.create({
contentContainerStyle: {
marginHorizontal: 5,
flex: 1
},
tabButtonContainerStyle: {
height: 50,
justifyContent: 'flex-end',
marginLeft: 0,
marginRight: 0,
marginBottom: 0
}
});
PurchaseMonth.defaultProps = {
purchases: []
};
PurchaseMonth.propTypes = {
purchases: PropTypes.array
};
const mapstateToProps = (state) => ({
profile: state.profile,
isLoading: state.uiLoading.isLoading,
purchases: state.purchases.purchasesMonth
});
export default connect(mapstateToProps, { getMonthPurchases })(PurchaseMonth);
- Подкомпонент 1: PurchaseMonthTable
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import PropTypes from 'prop-types';
import { Table, TableWrapper, Row } from 'react-native-table-component';
import { isArray } from 'lodash';
const element = (products, index) => (
<View style={styles.panelBottomStyle}>
<Text style={{color: '#00151C'}} numberOfLines={5}>
{isArray(products) ? products.join(" ") : ""}
</Text>
</View>
);
const PurchaseMonthTable = (props) => {
const { head, purchases } = props;
return (
<View style={styles.containerStyle}>
<Table borderStyle={{borderColor: 'transparent'}}>
<Row data={head} flexArr={[1, 1, 1, 1, 1]}
style={styles.headStyle} textStyle={styles.textStyle}
/>
{
purchases.length > 0 ?
purchases.map((rowData, index) => {
rowData.unshift(index + 1);
const products = rowData.pop();
return (
<TableWrapper key={index + "".toString()}
style={{marginBottom: 15}}>
<Row
key={"value" + index + "".toString()}
data={rowData}
textStyle={styles.textStyle}
/>
<Row
key={"product" + index + "".toString()}
data={[element(products, index)]}
/>
</TableWrapper>
)
})
:
<Row style={{marginTop: 50}}
data={['Aucune statistique pour ce mois.']}
flexArr={[1]}
textStyle={styles.textStyle}
/>
}
</Table>
</View>
);
}
PurchaseMonthTable.defaultProps = {
purchases: []
};
PurchaseMonthTable.propTypes = {
head: PropTypes.array.isRequired,
purchases: PropTypes.array
};
const styles = StyleSheet.create({
containerStyle: {
flex: 1,
marginTop: 20
},
headStyle: {
height: 40,
backgroundColor: '#7B7C9E'
},
textStyle: {
textAlign: 'center',
color: 'white'
},
panelBottomStyle: {
backgroundColor: 'white',
marginTop: 2,
marginHorizontal: 10,
padding: 5
}
});
export default PurchaseMonthTable;
- подкомпонент 2: PurchaseMonthChart
import React from 'react';
import { StyleSheet, View, Dimensions } from 'react-native';
import PropTypes from 'prop-types';
const deviceWidth = Dimensions.get('window').width;
const PurchaseMonthChart = (props) => {
const { purchases } = props;
return (
<View style={styles.containerStyle}>
</View>
);
}
PurchaseMonthChart.defaultProps = {
purchases: []
};
PurchaseMonthChart.propTypes = {
purchases: PropTypes.array
};
const styles = StyleSheet.create({
containerStyle: {
flex: 1,
marginTop: 50,
backgroundColor: 'white'
}
});
export default PurchaseMonthChart;
import React from 'react';
import { StyleSheet, View, FlatList, Text } from 'react-native';
const data = [
['BANANA', 15],
['POM', 15],
['MEAT', 15],
['RICE', 15],
['KOKI', 15]
];
const _renderItem = ({ item }) => (
<View style={styles.productContainerStyle}>
<View style={styles.producTitleStyle}>
<Text style={{color: 'white'}}>{item[0] + "".toUpperCase()}</Text>
</View>
<View><Text style={{color: 'white'}}>{item[1]}</Text></View>
</View>
);
const PurchaseMonthDetails = (props) => {
return (
<View style={styles.containerStyle}>
<FlatList
renderItem={_renderItem}
keyExtractor={(item, index) => index.toString()}
data={data}
/>
</View>
);
}
const styles = StyleSheet.create({
containerStyle: {
flex: 1,
marginTop: 20
},
productContainerStyle: {
flexDirection: 'row',
marginVertical: 5,
marginHorizontal: 10,
justifyContent: 'space-between',
alignItems: 'center'
},
producTitleStyle: {
borderRadius: 10,
backgroundColor: '#7B7C9E',
width: "40%",
height: 40,
justifyContent: 'center',
alignItems: 'center'
}
});
export default PurchaseMonthDetails;
- action: getMonthPurchases
export const getMonthPurchases = (numero, encryptedPass) => dispatch => {
dispatch(uiStartLoading());
if(!isEmpty(encryptedPass)) {
const password = decryptPass(encryptedPass);
getPurchases(numero, password, true).then(
(data) => {
const dayOfMonth = (new Date()).getDate();
const purchases = [];
for(i = 0; i < dayOfMonth; i++) {
purchases[i] = [0, 0, 0, 0, []];
}
data.forEach(element => {
switch (element.famille) {
case "B1":
purchases[element.jour - 1][0] += element.quantite;
break;
case "B2":
purchases[element.jour - 1][1] += element.quantite;
break;
case "B3":
case "B4":
purchases[element.jour - 1][2] += element.quantite;
break;
default:
break;
}
purchases[element.jour - 1][3] += element.montant;
purchases[element.jour - 1][4].push(element.produit);
});
dispatch({
type: GET_MONTH_PURCHASE,
value: purchases
});
dispatch(uiStopLoading());
}
).catch((error) => {
dispatch(uiStopLoading());
toast(CONNEXION_PROBLEM_MSG, "danger", 10000);
});
} else {
dispatch(uiStopLoading());
}
}
- Редуктор: покупки редуктор
import {
GET_MONTH_PURCHASE,
GET_YEAR_PURCHASE,
} from "../actions/types";
const initialState = {
purchasesMonth: [],
purchasesYear: [],
products: []
};
export default function(state = initialState, action) {
let newState;
switch (action.type) {
case GET_MONTH_PURCHASE:
newState = {
...state,
purchasesMonth: action.value
}
break;
case GET_YEAR_PURCHASE:
newState = {
...state,
purchasesYear: action.value
}
break;
default:
newState = state;
break;
}
return newState || state;
}
Для отладки я использую собственный встроенный отладчик, чтобы получить этот снимок экрана (генерируется консольным журналом в родительском компоненте PurchaseMonth):