Javascript React native/redux-在现有状态转换期间无法更新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 {

我正在使用React Native和redux开发一个应用程序。expressjs用于Ajax请求

我的Ajax请求中的数据不会加载,下面是我收到的警告:

警告:setState(…):无法在现有状态期间更新 转换(例如在
渲染
或其他组件的 构造函数)。渲染方法应该是道具和工具的纯功能 国家;构造函数的副作用是一种反模式,但可以移动 到
组件将装入

不完全确定我做错了什么

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