反应:在渲染方法中调用setState会引发错误

时间:2018-10-17 03:58:16

标签: javascript reactjs

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

我还在按钮类和'parent'类中尝试了显示逻辑,这是我的消息列表,我将按钮放入其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;

和我的messageList类,其中有this.props.messages,它是消息的数组,this.props.messages [0]是第一条消息,而message ..,如果我进行控制台,则控制台的每条消息记录下来。

如果我写了一个(如果message.data.text或this.props.messages [0] ==='我的第一个字符串'){console.log('.....'},那么它总是算作true和控制台,并且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>)
  }
}

我不确定我的逻辑是否在错误的地方?我尝试过多次移动它,我是React的新手!

1 个答案:

答案 0 :(得分:2)

首先,问题是您通过在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>)
  }
}