当前位置: 首页 > 知识库问答 >
问题:

反应:警告setState无法在现有状态转换期间更新(例如在渲染中)

傅玮
2023-03-14

错误消息:

反应:警告setState无法在现有状态转换期间更新(例如在渲染中)

这是一个react原生应用程序,但我认为,这更多的是一个react问题。

我得到了标题中描述的错误。但我对原因感到困惑,我没有在任何父组件或子组件中设置状态。因此,我有一个孙子组件(CardLayoutResult),它呈现一个listView,每一行呈现一个新组件(Render row),该组件有一个单击事件,单击它会从props调用一个函数(onselectLayout)(从父组件(个性化组件)(父函数setCardTemplate)传递)。然后,此父函数调用父内部状态的setState。然后进行重新渲染。

为什么我得到这个错误点击?

父组件

export class Personalization extends Component {

constructor(props) {
 super(props);

 this.state = {
   showModel: true,
   editorState: {}
 };

  this.setCardTemplate = this.setCardTemplate.bind(this);
}

setCardTemplate(selectedTemplateObj){
  console.log(JSON.stringify(selectedTemplateObj));
  this.setState({
    showModel: false,
    editorState: selectedTemplateObj
  });
}

render() {
  return (
   <View>
     <CreateCardStep containerState={{showModel:this.state.showModel ,
              editorState: this.state.editorState 
              setCardTemplate:this.setCardTemplate}} />
   </View>
  )
}

子组件

const CreateCardStep = (_props)  => {
  return (
    <View>
       <CardLayoutResults containerState={_props.containerState} />
    </View>
  );
}

大孩子组件

export class CardLayoutResults extends Component {
  constructor(props) {
      super(props);
  }
  render() {

   return(

    <View>
      <ListView
        RenderRow = {(data) => <RenderRow styles={styles} rowObj={data} onSelectLayout={this.props.containerState.setCardTemplate} /> } 
    </View>    
   )
  }

渲染行

 const RenderRow = (props) => {
  let base64Image = 'data:image/png;base64,'.concat(props.rowObj.base);

 return (
 <View style={props.styles.templateImage}>
   <TouchableHighlight onPress={() => props.onSelectLayout(props.rowObj)}>
     <Image style={props.styles.thumbnail} resizeMode= {Image.resizeMode.contain} source={{uri: base64Image}}/>
   </TouchableHighlight>
 </View>
 );
};

-更新此问题似乎是在setCardTemplate函数中设置状态时出现的

共有3个答案

奚翰海
2023-03-14

问题在于您将道具从父组件传递给子组件的方式。

在这个片段中

 <CreateCardStep containerState={{showModel:this.state.showModel ,
          editorState: this.state.editorState 
          setCardTemplate:(val) => this.setCardTemplate(val)}} />

当将函数作为道具本身传递时,您正在调用函数,因此每次组件渲染时,都会设置状态,这很好。

但是,当您单击“渲染行”时,在完成渲染循环之前,仍将为同一属性设置组件状态,这会导致此警告。

要修复它,只需将父函数作为setCardTemplate:this传递。设置卡片模板。它将仅在按行时设置状态(并在内部调用渲染),而不是每次渲染时

吕高昂
2023-03-14

我猜listView的renderRow调用不正确

尝试

<View>
  <ListView
    renderRow = {(data) => <RenderRow rowObj={data} onSelectLayout={this.props.containerState.setCardTemplate} />} 
   />
</View>

从个性化组件中传递道具,比如

return (
   <View>
     <CreateCardStep containerState={{showModel:this.state.showModel ,
              editorState: this.state.editorState 
              setCardTemplate:(val) => this.setCardTemplate(val)}} />
   </View>
  )   
别浩漫
2023-03-14

您需要在构造函数中绑定setCardTemplate函数,或者从lambda函数调用它(绑定更好)

<View>
      <ListView renderRow = {(data => rowObj={data}} onSelectLayout={() => this.props.containerState.setCardTemplate} />
</View>
 类似资料:
  • 我正在开发一个简单的待办事项列表反应应用程序(新的React.js)。我已经将项目添加到工作列表中,但删除项目会引起一个问题。在我的父反应组件中,我有以下代码: 我的组件: 运行此代码将带来: 警告:setState(...):无法在现有状态转换期间更新 问题: 为什么的渲染在添加项时立即执行回调,即: 但是,添加以删除Callback ie。

  • 问题内容: 我正在尝试从渲染视图重构以下代码: 到绑定位于构造函数内的版本。原因是渲染视图中的绑定会给我带来性能问题,尤其是在低端手机上。 我创建了以下代码,但是我不断收到以下错误(很多错误)。该应用似乎陷入了循环: 以下是我使用的代码: 问题答案: 看起来您不小心在render方法中调用了该方法,而您可能想这样做。 如果您不想在onClick处理程序中创建lambda,我认为您将需要两个绑定方法

  • 我正在重写一些旧的ReactJS代码,但在修复此错误时遇到了麻烦(此错误在控制台中重复大约1700次,DOM根本不呈现): 警告:设置状态(…):无法在现有状态转换期间更新(例如在或其他组件的构造函数中)。渲染方法应该是道具和状态的纯函数;构造函数的副作用是一种反模式,但可以移动到。 我是一个组件,它将它的状态传递给一个应该呈现一些控件的组件。基于单击的控件,状态应该更改,并且应该呈现新的控件。

  • 在进一步的调试中,我发现,以上可能不是根本原因,毕竟,我可以保留通知,但我需要删除我的重定向。

  • 当我试图插入一个新的食谱元素时,我的项目总是崩溃。我使用在能够根据需要更新食谱(例如删除,编辑等)。 如果我将语句切换到,我可以插入元素而没有问题,但是由于删除,我无法删除触发状态更改,并需要状态更改来反映更新而不是道具。有人对这个问题有什么建议吗?谢谢! 配方列表: 配方容器: 配方表: