Почему мой реагирующий компонент отключается каждый раз, когда его реквизиты обновляются через Flux Store?
У меня есть реактивный компонент (это реактивно-нативные проекты). в componentDidMount я делаю ajax-вызовы, чтобы получить некоторые данные, а затем я обновляю хранилище потоков, которое передает реквизиты этого компонента. однако каждый раз, когда состояние хранилища потока обновляется, компонент отключается и снова монтируется, поэтому это приводит к тому, что он попадает в бесконечный цикл. Это не похоже на ожидаемое поведение реагирующего компонента. введите код сюда. это мой компонент:
export default class InitializeView extends React.Component {
constructor(props) {
super(props);
this._loadWorkList = this._loadWorkList.bind(this);
this.state = {
loadingWorkForms: true,
loadingPointForms: true,
loadingWorks: true,
loadingPoints: true,
loadingIcons: true,
loadingPointFiles: true,
}
}
_loadWorkList() {
AsyncStorage.getItem('apiKey').then((apiKey) => {
Reactotron.log(apiKey);
if(this.props.works.length === 0 ) {
Api.getWorks(apiKey).then(works => {
this.props.onLoadWorks(JSON.parse(works));
this.setState({
loadingWorks: false,
})
});
}
Api.getPointForms(apiKey).then(pointForms => {
this.props.onLoadPointFormSchemes(JSON.parse(pointForms));
this.setState({
loadingPointForms: false,
})
});
Api.getWorkForms(apiKey).then(workForms => {
this.props.onLoadWorkFormSchemes(JSON.parse(workForms));
this.setState({
loadingWorkForms: false,
})
});
Api.getPointForms(apiKey).then(forms => {
Api.getIcons(apiKey).then(icons => {
Api.getWorkPoints(apiKey, this.props.app.activeWork).then((points) => {
this.props.onLoadWorkPoints(JSON.parse(points), JSON.parse(icons), JSON.parse(forms));
this.setState({
loadingPoints: false,
loadingIcons: false,
loadingPointFiles: false
})
})
})
})
}).done();
}
componentDidMount() {
Reactotron.log('initialize View is mounted!');
this._loadWorkList();
}
componentWillUnmount(){
Reactotron.log('initializeView is Unmounting');
}
render() {
return (<View style={{marginTop: 50,}} key="render_only_once" id="whatTheFuck">
<View key={1} style={styles.row}>
{this.state.loadingWorkForms ? <ActivityIndicator animating={true} size='small' /> : <MaterialCommunityIcons name='check' size={25} style={styles.icon}/>}
<Text style={styles.text}>{this.state.loadingWorkForms ? 'Downloading Work Forms...' : `Downloaded ${this.props.workFormSchemes.lenght} work forms`}</Text>
</View>
<View key={2} style={styles.row}>{ this.state.loadingPointForms ? <Text style={styles.text}>{'Downloading Point Forms...'}</Text> : <Text style={styles.text}>{`Downloaded ${this.props.workFormSchemes.lenght} work forms`}</Text> }</View>
<View key={3} style={styles.row}>{ this.state.loadingWorks ? <Text style={styles.text}>{'Downloading Work Forms...'}</Text> : <Text style={styles.text}>{`Downloaded ${this.props.workFormSchemes.lenght} work forms`}</Text> }</View>
<View key={4} style={styles.row}>{ this.state.loadingPoints ? <Text style={styles.text}>{'Downloading Point Forms...'}</Text> : <Text style={styles.text}>{`Downloaded ${this.props.workFormSchemes.lenght} work forms`}</Text> }</View>
<View key={5} style={styles.row}>{ this.state.loadingIcons ? <Text style={styles.text}>{'Downloading Icons...'}</Text> : <Text style={styles.text}>{`Downloaded ${this.props.workFormSchemes.lenght} work forms`}</Text> }</View>
<View key={6} style={styles.row}>{ this.state.loadingPointFiles ? <Text style={styles.text}>{'Downloading Points Files...'}</Text> : <Text style={styles.text}>{`Downloaded ${this.props.workFormSchemes.lenght} work forms`}</Text> }</View>
</View>)
}
}
//flux container component
export default class AppContainer extends React.Component {
static getStores() {
return [
LoginStore,
WorkFormSchemeStore,
PointFormSchemeStore,
WorkStore,
AppStore,
];
}
static getState() {
return {
loginState: LoginStore.getState(),
onLoggedIn: LoginActions.loggedIn,
onLoginFailed: LoginActions.loginFailed,
onLoggedOut: LoginActions.loggedOut,
workFormSchemes: WorkFormSchemeStore.getState(),
pointFormSchemes: PointFormSchemeStore.getState(),
onLoadWorkFormSchemes: WorkFormSchemeActions.loadWorkFormSchemes,
onLoadPointFormSchemes: PointFormSchemeActions.loadPointFormSchemes,
works: WorkStore.getState(),
onLoadWorks: WorkActions.loadWorks,
points: WorkPointsStore.getState(),
onLoadWorkPoints: WorkPointsActions.loadWorkPoints,
app: AppStore.getState(),
onSetActiveWork: AppActions.setActiveWork,
onSetActivePoint: AppActions.setActivePoint,
onSetActiveFile: AppActions.setActiveFile,
};
}
static calculateState(prevState) {
Reactotron.log('app state changed');
return{
loginState: LoginStore.getState(),
onLoggedIn: LoginActions.loggedIn,
onLoginFailed: LoginActions.loginFailed,
onLoggedOut: LoginActions.loggedOut,
workFormSchemes: WorkFormSchemeStore.getState(),
pointFormSchemes: PointFormSchemeStore.getState(),
onLoadWorkFormSchemes: WorkFormSchemeActions.loadWorkFormSchemes,
onLoadPointFormSchemes: PointFormSchemeActions.loadPointFormSchemes,
works: WorkStore.getState(),
onLoadWorks: WorkActions.loadWorks,
points: WorkPointsStore.getState(),
onLoadWorkPoints: WorkPointsActions.loadWorkPoints,
app: AppStore.getState(),
onSetActiveWork: AppActions.setActiveWork,
onSetActivePoint: AppActions.setActivePoint,
onSetActiveFile: AppActions.setActiveFile,
};
}
componentDidMount() {
//Reactotron.log(a)
}
render() {
return (!this.state.loginState.loggedIn ? <LoginView {...this.state} {...this.props}/> : <DataCollectionStack key="appstack" {...this.state} {...this.props}/>)
}
}
//parent of the component (stack navigator)
export default class DataCollectionStack extends React.Component {
constructor (props) {
super (props);
}
render() {
Reactotron.log(this.props);
const DrawerNavigationComponent = ({navigation}) => (
<DrawerNavigation key="drawerNavigationComponent" stackNavigation={navigation} {...this.props}/>
);
const ErrorScreen = ({navigation}) => (
<ErrorView key="errorScreen" navigation={navigation} />
);
const CreatePointScreen = ({navigation}) => (
<CreatePoint key="createPointScreen" navigation={navigation} {...this.props}/>
);
const InitialScreen = ({navigation}) => (
<InitializeView key="initialScreen" navigation={navigation} {...this.props}/>
)
const AppStack = StackNavigator({
Initial: {
screen: InitialScreen,
path:'/',
navigationOptions: ({navigation}) => ({
header: null,
})
},
Drawer: {
screen: DrawerNavigationComponent,
path:'/main',
navigationOptions: ({navigation}) => ({
header: null,
})
},
PointView: {
screen: PointFormContainer,
path:'/point',
navigationOptions: ({navigation}) => ({
title: 'Point',
headerStyle: styles.stackHeader,
headerRight: <TouchableOpacity style={styles.doneButton} onPress={() => {navigation.goBack()}}><MaterialIcons name='done' size={40} color={'#419388'}/></TouchableOpacity>
})
},
CreatePoint: {
screen: CreatePointScreen,
path:'/create',
navigationOptions: ({navigation}) => ({
title: 'New Point',
headerStyle: styles.stackHeader,
headerRight: <TouchableOpacity style={styles.doneButton} onPress={() => {navigation.goBack()}}><MaterialIcons name='done' size={40} color={'#419388'}/></TouchableOpacity>
})
},
Error: {
screen: ErrorScreen,
path:'/error',
navigationOptions: ({navigation}) => ({
title: `Point ID: ${navigation.state.params.point.id}`,
headerStyle: styles.stackHeader,
})
},
},
{
headerMode : 'screen'
},
{
initialRouteName: 'Drawer',
}
);
return <AppStack/>
}
}