Я разрабатываю приложение с использованием React Native и redux. Экспресс js для запросов Ajax.React native/redux - setState не может обновляться во время существующего перехода состояния
Данные из моего запроса Ajax не загрузит и вот предупреждение я получаю:
Предупреждение: SetState (...): Не удается обновить в течение существующего состояния перехода (например, в пределах
render
или конструктор другого компонента ). Методы рендеринга должны быть чистой функцией реквизита и состояния ; побочные эффекты конструктора являются анти-образными, но могут быть перемещены вcomponentWillMount
.
Не совсем уверен, что я делаю неправильно?
index.ios.js
import React, { Component } from 'react'
import {
AppRegistry,
StyleSheet,
Text,
View,
NavigatorIOS
} from 'react-native'
import { Provider } from 'react-redux'
import store from './src/store'
import CategoryView from './src/category-view'
class myApp extends Component {
render() {
return (
<Provider store={store}>
<NavigatorIOS
initialRoute={{
component: CategoryView,
title: 'myApp',
index: 0
}}
/>
</Provider>
);
}
}
store.js
import { combineReducers, createStore, applyMiddleware } from 'redux'
import thunkMiddleware from 'redux-thunk'
import category from './reducers/category'
import listings from './reducers/listings'
const reducers = combineReducers({
category,
listings
})
const initialState = {}
const store = createStore(
reducers,
initialState,
applyMiddleware(
thunkMiddleware
)
)
export default store
Вот мой вид файла:
import React from 'react'
import {
View,
ListView,
ScrollView,
StyleSheet,
Image,
TouchableHighlight
} from 'react-native'
import { connect } from 'react-redux'
import Listings from './listings'
import BetView from './bet-view'
import { getListings } from './actions/listings'
const getDataSource = (listings) =>
(new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 != r2
})).cloneWithRows(listings)
const _ListingsView = ({dataSource, navigator, onPress, onLoad}) => {
onLoad()
return(
<ScrollView>
<ListView
dataSource={dataSource}
renderRow={(row) =>
<Listings
teamOne={row.game[0]}
teamTwo={row.game[1]}
date={row.date}
onPress={() => onPress(navigator, row.name)}
/>
}
/>
</ScrollView>
)
}
const ListingsView = connect(
(state) => {
return {
dataSource: getDataSource(state.listings.items || []),
loading: state.listings.loading
}
},
(dispatch) => {
return {
onPress: (navigator, name) =>
navigator.push({
title: 'test',
component: BetView,
passProps: {
category: name
}
}),
onLoad:() => dispatch(getListings())
}
}
)(_ListingsView)
export default ListingsView
Действие Файл:
const URL = 'http://localhost:3000/listings'
export const REQUEST_LISTINGS = 'request-listings'
export const RECEIVE_LISTINGS = 'receive-listings'
const requestListings =() =>
({
type: REQUEST_LISTINGS
})
const receiveListings = (items) =>
({
type: RECEIVE_LISTINGS,
items: items || []
})
const shouldFetch = (state) => {
const res = (!state.listings.items || 0 == state.listings.items.length && !state.listings.loading)
return res
}
export const getListings =() =>
(dispatch, getState) =>
shouldFetch(getState())
&& dispatch(requestListings())
&& fetch(URL)
.then(res => res.json())
.then(json => dispatch(receiveListings(json)))
Вот редуктор:
import { RECEIVE_LISTINGS, REQUEST_LISTINGS } from '../actions/listings'
export default (state = {}, action) => {
switch (action.type) {
case RECEIVE_LISTINGS:
return {
loading: false,
items: action.items
}
case REQUEST_LISTINGS:
return {
loading: true,
items: []
}
}
return state
}
Есть ли в вашем приложении какие-либо компоненты, которые используют локальное состояние? Другими словами, вы вызываете 'setState' где угодно? –
Эта ошибка обычно возникает, когда вы пытаетесь обновить состояние в функции рендеринга. Реакция декларативна, поэтому рендер не должен манипулировать состоянием. –
Возможно, вы используете компонент без состояния, и все происходит во время метода рендеринга. С базовым компонентом класса вы можете подключить getDataSource внутри componentWillMount –