Javascript React native/redux-在现有状态转换期间无法更新setState
我正在使用React Native和redux开发一个应用程序。expressjs用于Ajax请求 我的Ajax请求中的数据不会加载,下面是我收到的警告: 警告:setState(…):无法在现有状态期间更新 转换(例如在Javascript React native/redux-在现有状态转换期间无法更新setState,javascript,express,react-native,react-redux,setstate,Javascript,Express,React Native,React Redux,Setstate,我正在使用React Native和redux开发一个应用程序。expressjs用于Ajax请求 我的Ajax请求中的数据不会加载,下面是我收到的警告: 警告:setState(…):无法在现有状态期间更新 转换(例如在渲染或其他组件的 构造函数)。渲染方法应该是道具和工具的纯功能 国家;构造函数的副作用是一种反模式,但可以移动 到组件将装入 不完全确定我做错了什么 index.ios.js import React, { Component } from 'react' import {
渲染
或其他组件的
构造函数)。渲染方法应该是道具和工具的纯功能
国家;构造函数的副作用是一种反模式,但可以移动
到组件将装入
不完全确定我做错了什么
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>
);
}
}
这是我的视图文件:
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
这是减速器:
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
}
你可以试试这样的。我还没有测试过。我不确定它是否完美。但这就是想法
import React, {Component} 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)
class _ListingsView extends Component {
componentWillMount() {
this.props.onLoad();
}
render() {
return(
<ScrollView>
<ListView
dataSource={this.props.dataSource}
renderRow={(row) =>
<Listings
teamOne={row.game[0]}
teamTwo={row.game[1]}
date={row.date}
onPress={() => this.props.onPress(this.props.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
import React,{Component}来自“React”
进口{
看法
ListView,
滚动视图,
样式表,
形象,,
可触摸高光
}从“反应本机”
从“react redux”导入{connect}
从“./Listings”导入列表
从“./bet视图”导入BetView
从“./actions/listings”导入{getListings}
const getDataSource=(列表)=>
(新建ListView.DataSource({
行已更改:(r1,r2)=>r1!=r2
})).cloneWithRows(列表)
类_ListingsView扩展组件{
组件willmount(){
this.props.onLoad();
}
render(){
返回(
this.props.onPress(this.props.navigator,row.name)}
/>
}
/>
)
}
}
const ListingsView=connect(
(州)=>{
返回{
dataSource:getDataSource(state.listings.items | | |[]),
加载:state.listings.loading
}
},
(调度)=>{
返回{
onPress:(导航器,名称)=>
导航器。推({
标题:"测试",,
组件:BetView,
通行证:{
类别:姓名
}
}),
onLoad:()=>dispatch(getListings())
}
}
)(_ListingsView)
导出默认列表视图
因此,您最好以他们为例:
或者这就是我在当前构建的应用程序中管理ListView的方式:
(在该示例中有点不同,因为对api的调用甚至在呈现该组件和筛选列表之前就已经进行了,这就是我在componentWillReceiveProps中更新数据源状态的原因)您的应用程序中是否有使用本地状态的组件?换句话说,您是否在任何地方调用setState
?此错误通常在尝试更新渲染函数中的状态时发生。React是声明性的,因此render不应操纵状态。这可能是因为您使用的是无状态组件,并且在render方法期间发生的一切。使用类基组件,您可以在组件willmount内连接getDataSource,您可以在\u ListingsView
的render()
方法中调用onLoad()
。使用组件生命周期方法,如componentWillMount
来避免这种情况。我刚刚更新了我的问题,并添加了index.ios.js来显示渲染方法。非常感谢。我将尝试一下并让您知道。您的解决方案确实修复了setState警告,但数据仍然没有加载。可能与它所抱怨的另一个问题有关:可能未处理的承诺拒绝(id:0):React.Children。只希望接收单个React元素子元素。不变冲突:React.Children.仅应接收单个React元素子元素。您能否指出错误来自完整堆栈跟踪中的哪个组件?看到您创建的任何组件了吗?react组件必须返回一个节点(例如:)作为错误源。它必须只有一个孩子。非常感谢你的帮助。
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
}
import React, {Component} 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)
class _ListingsView extends Component {
componentWillMount() {
this.props.onLoad();
}
render() {
return(
<ScrollView>
<ListView
dataSource={this.props.dataSource}
renderRow={(row) =>
<Listings
teamOne={row.game[0]}
teamTwo={row.game[1]}
date={row.date}
onPress={() => this.props.onPress(this.props.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