Javascript 反应:在render方法内调用setState会引发错误

Javascript 反应:在render方法内调用setState会引发错误,javascript,reactjs,Javascript,Reactjs,正如标题所示,只有在我的聊天窗口中收到第一条消息后(此初始消息是从GET请求中检索的,因此它不是同步的),我才想显示/呈现一个按钮。此时,它抛出一个错误,表示我无法在render方法中设置状态 我还尝试了button类中的show逻辑以及“parent”类,它是我的messagelist,我将按钮放在它的render方法中 这里有this.props.messages,它是一个消息数组,“messages”也是如此。this.props.messages[0].data.text是第一条消息,尽

正如标题所示,只有在我的聊天窗口中收到第一条消息后(此初始消息是从GET请求中检索的,因此它不是同步的),我才想显示/呈现一个按钮。此时,它抛出一个错误,表示我无法在render方法中设置状态

我还尝试了button类中的show逻辑以及“parent”类,它是我的messagelist,我将按钮放在它的render方法中

这里有this.props.messages,它是一个消息数组,“messages”也是如此。this.props.messages[0].data.text是第一条消息,尽管当我尝试控制台时,它会多次控制台开发工具中的每条消息,当然,当我尝试显示按钮时,它会抛出setState错误

我有一个简单的按钮类:

class Button extends Component {
render() {
    return (
        <div>
            {<button>Return</button >}
        </div>
    )
  }
}
export default Button;
class按钮扩展组件{
render(){
返回(
{Return}
)
}
}
导出默认按钮;
还有我的messageList类,其中我有this.props.messages,它是一个消息数组,this.props.messages[0]是第一条消息,message..如果我是console.log,它是每个消息的控制台

如果我写入任何一个(如果message.data.text或this.props.messages[0]==='my first string'){console.log('..…'),则它始终计为true,consoles和setstate进入循环

import Message from './Messages'
import Button from './Button'


class MessageList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showing: false,
    };
    this.showButton = this.showButton.bind(this);
  }

  showButton() {
    const { showing } = this.state;
    this.setState({
      // toggle value of `showing`
      showing: !showing,

    });
  }

  componentDidUpdate(prevProps, prevState) {
    this.scrollList.scrollTop = this.scrollList.scrollHeight;
  }

  onlyInitialMessage(message) {
    if (this.props.messages[0].data.text = `Hi I'm Joe your store assistant, I'm here to help. Here's what I can do: Answer questions on store policies, process a return or just general inquiries.`) {
      this.showButton();
    }
  }

  // way to render a function.
  // {this.renderIcon()}   


  render() {
    return (
      <div className="sc-message-list" ref={el => this.scrollList = el}>
        {this.props.messages.map((message, i) => {

          { this.onlyInitialMessage() }

          return <Message message={message} key={i} />
        })}

        {this.state.showing && <Button />}

      </div>)
  }
}
从“./Messages”导入消息
从“./按钮”导入按钮
类MessageList扩展组件{
建造师(道具){
超级(道具);
此.state={
显示:错误,
};
this.showButton=this.showButton.bind(this);
}
showButton(){
const{showing}=this.state;
这是我的国家({
//切换“显示”的值`
展示:!展示,
});
}
componentDidUpdate(prevProps、prevState){
this.scrollList.scrollTop=this.scrollList.scrollHeight;
}
仅限初始消息(消息){
if(this.props.messages[0].data.text=`你好,我是你的商店助理乔,我是来帮忙的。我能做的是:回答有关商店政策的问题、处理退货或只是一般查询。`){
这个.showButton();
}
}
//呈现函数的方法。
//{this.renderIcon()}
render(){
返回(
this.scrollList=el}>
{this.props.messages.map((message,i)=>{
{this.onlyInitialMessage()}
返回
})}
{this.state.showing&&}
)
}
}

我不确定我的逻辑是否放错地方了?我尝试过多次移动它,我还没有反应过!

首先,问题是您通过在render中调用
{this.onlyInitialMessage()}
来间接设置render方法中的状态

其次,您的if条件不是比较值而是赋值,该赋值将始终返回true

if (this.props.messages[0].data.text === `Hi I'm Joe your store assistant, I'm here to help. Here's what I can do: Answer questions on store policies, process a return or just general inquiries.`) {
要解决此问题,必须在componentDidMount中调用
onlyInitialMessage

import Message from './Messages'
import Button from './Button'


class MessageList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showing: false,
    };
    this.showButton = this.showButton.bind(this);
  }
  componentDidMount() {
      this.onlyInitialMessage();
  }
  showButton() {
    const { showing } = this.state;
    this.setState({
      // toggle value of `showing`
      showing: !showing,

    });
  }

  componentDidUpdate(prevProps, prevState) {
    this.scrollList.scrollTop = this.scrollList.scrollHeight;
  }

  onlyInitialMessage(message) {
    if (this.props.messages[0].data.text == `Hi I'm Joe your store assistant, I'm here to help. Here's what I can do: Answer questions on store policies, process a return or just general inquiries.`) {
      this.showButton();
    }
  }

  // way to render a function.
  // {this.renderIcon()}   


  render() {
    return (
      <div className="sc-message-list" ref={el => this.scrollList = el}>
        {this.props.messages.map((message, i) => {

          return <Message message={message} key={i} />
        })}

        {this.state.showing && <Button />}

      </div>)
  }
}
从“./Messages”导入消息
从“./按钮”导入按钮
类MessageList扩展组件{
建造师(道具){
超级(道具);
此.state={
显示:错误,
};
this.showButton=this.showButton.bind(this);
}
componentDidMount(){
此.onlyInitialMessage()为;
}
showButton(){
const{showing}=this.state;
这是我的国家({
//切换“显示”的值`
展示:!展示,
});
}
componentDidUpdate(prevProps、prevState){
this.scrollList.scrollTop=this.scrollList.scrollHeight;
}
仅限初始消息(消息){
if(this.props.messages[0].data.text=`嗨,我是你的商店助理乔,我是来帮忙的。我能做的是:回答有关商店政策的问题,处理退货或只是一般查询。`){
这个.showButton();
}
}
//呈现函数的方法。
//{this.renderIcon()}
render(){
返回(
this.scrollList=el}>
{this.props.messages.map((message,i)=>{
返回
})}
{this.state.showing&&}
)
}
}

首先,问题是通过在render中调用
{this.onlyInitialMessage()}
间接设置render方法中的状态

其次,您的if条件不是比较值而是赋值,该赋值将始终返回true

if (this.props.messages[0].data.text === `Hi I'm Joe your store assistant, I'm here to help. Here's what I can do: Answer questions on store policies, process a return or just general inquiries.`) {
要解决此问题,必须在componentDidMount中调用
onlyInitialMessage

import Message from './Messages'
import Button from './Button'


class MessageList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showing: false,
    };
    this.showButton = this.showButton.bind(this);
  }
  componentDidMount() {
      this.onlyInitialMessage();
  }
  showButton() {
    const { showing } = this.state;
    this.setState({
      // toggle value of `showing`
      showing: !showing,

    });
  }

  componentDidUpdate(prevProps, prevState) {
    this.scrollList.scrollTop = this.scrollList.scrollHeight;
  }

  onlyInitialMessage(message) {
    if (this.props.messages[0].data.text == `Hi I'm Joe your store assistant, I'm here to help. Here's what I can do: Answer questions on store policies, process a return or just general inquiries.`) {
      this.showButton();
    }
  }

  // way to render a function.
  // {this.renderIcon()}   


  render() {
    return (
      <div className="sc-message-list" ref={el => this.scrollList = el}>
        {this.props.messages.map((message, i) => {

          return <Message message={message} key={i} />
        })}

        {this.state.showing && <Button />}

      </div>)
  }
}
从“./Messages”导入消息
从“./按钮”导入按钮
类MessageList扩展组件{
建造师(道具){
超级(道具);
此.state={
显示:错误,
};
this.showButton=this.showButton.bind(this);
}
componentDidMount(){
此.onlyInitialMessage()为;
}
showButton(){
const{showing}=this.state;
这是我的国家({
//切换“显示”的值`
展示:!展示,
});
}
componentDidUpdate(prevProps、prevState){
this.scrollList.scrollTop=this.scrollList.scrollHeight;
}
仅限初始消息(消息){
if(this.props.messages[0].data.text=`嗨,我是你的商店助理乔,我是来帮忙的。我能做的是:回答有关商店政策的问题,处理退货或只是一般查询。`){
这个.showButton();
}
}
//呈现函数的方法。
//{this.renderIcon()}
render(){
返回(
this.scrollList=el}>
{this.props.messages.map((message,i)=>{
返回
})}
{this.state.showing&&}
)
}
}

我应该提到,我的初始消息是从GET请求中检索到的,因此它与componentDidMount不同步-没有显示任何内容!如果我将其注释掉,它会返回。好的,那么您需要做的是在检查props是否真的发生了更改后调用componentDidUpdate中的setState di GET-“无法读取未定义的属性”数据“……这是一个聊天窗口,因此信息不在那里,而是通过请求返回的。哦,好的,我会的。”