React Chatbox,如何显示字符串?

React Chatbox, how to get the string displayed?

我是新手,正在尝试使用 AWS 和 React 构建一个简单的餐厅推荐 Web 应用程序。所以,我正在使用这个聊天 window(https://www.npmjs.com/package/react-chat-window)。基本上,当用户键入内容时,聊天机器人会被触发并询问 "what kind of food do you want?" 之类的问题。到目前为止,我能够传递用户的输入并从 AWS 获得响应。我可以将响应记录到控制台并进行验证。但是我无法在聊天框中显示回复。

这是代码片段

class chatBox extends Component {
    constructor() {
        super();
        this.state = {
            messageList: chatHistory,
            newMessagesCount: 0,
            isOpen: false
        };
    }

    // message is the user's input
    _onMessageWasSent(message) {
        var body = {
            messages: message.data['text']
        }
        // every time the user types something, this function passes the user's input to AWS
        apigClient.invokeApi(pathParams, pathTemplate, method, additionalParams, body)
            .then(function (result) { // result contains the response to the user's input
                var text = result.data.body
                console.log(text)   // logs the response to the user's input
                console.log(text.length)
            }).catch(function (result) {
            });

        this.setState({ //this displays what the user types
            messageList: [...this.state.messageList, message]
        })
    }


    // This is a function that displays the input of the other side
    // I can manually test it and see that whatever I pass to this function gets displayed as
    // the other person's speech, not the user.
    _sendMessage(text) {
        console.log("sendMessage")
        if (text.length > 0) {
            this.setState({
                messageList: [...this.state.messageList, {
                    author: 'them',
                    type: 'text',
                    data: { text }
                }],
                newMessagesCount: this.state.newMessagesCount + 1
            })
        }
    }

可以看出,我正在将响应记录到控制台。现在,我想显示响应,所以我在构造函数中尝试

this._onMessageWasSent = this._sendMessage.bind(this)

并调用_onMessageSent里面的函数

apigClient.invokeApi(pathParams, pathTemplate, method, additionalParams, body)
            .then(function (result) { // result contains the response to the user's input
                var text = result.data.body
                console.log(text)   // logs the response to the user's input
                console.log(text.length)
                this._sendMessage(text) // Calling the function
            }).catch(function (result) {
            });

        this.setState({ //this displays what the user types
            messageList: [...this.state.messageList, message]
        })
    }

我可以看到 _sendMessage 函数被触发,因为我有一个 console.log。但是现在聊天框既不显示用户也不显示聊天机器人。如果我不绑定 this._onMessageWasSent = this._sendMessage.bind(this),至少我会显示用户。

可能是什么问题??

这是我的渲染器()

render() {
        return (<div>
            <Launcher
                agentProfile={{
                    teamName: 'Foodophile',
                    imageUrl: 'https://a.slack-edge.com/66f9/img/avatars-teams/ava_0001-34.png'
                }}
                onMessageWasSent={this._onMessageWasSent.bind(this)}
                messageList={this.state.messageList}
                onFilesSelected={this._onFilesSelected.bind(this)}
                newMessagesCount={this.state.newMessagesCount}
                handleClick={this._handleClick.bind(this)}
                isOpen={this.state.isOpen}
                showEmoji
            />
        </div>)
    }

更新

class chatBox extends Component {
    constructor(props) {
        super(props);
        this.state = {
            messageList: chatHistory,
            newMessagesCount: 0,
            isOpen: false
        };
        this._onMessageWasSent = this._onMessageWasSent.bind(this);
        this._onFilesSelected = this._onFilesSelected.bind(this);
        this._handleClick = this._handleClick.bind(this);
        this._sendMessage = this._sendMessage.bind(this);
    }
    _onMessageWasSent(message) {
        var body = {
            messages: message.data['text']
        }

        apigClient.invokeApi(pathParams, pathTemplate, method, additionalParams, body)
            .then(function (result) {
                var text = result.data.body
                console.log(text)
                console.log(text.length)
                this._sendMessage(text)
            }).catch(function (result) {
            });
        this.setState({
            messageList: [...this.state.messageList, message]
        })
    }

    _sendMessage(text) {
        console.log("sendMessage")
        if (text.length > 0) {
            this.setState({
                messageList: [...this.state.messageList, {
                    author: 'them',
                    type: 'text',
                    data: { text }
                }],
                newMessagesCount: this.state.newMessagesCount + 1
            })
        }
    }
    render() {
        return (<div>
            <Launcher
                agentProfile={{
                    teamName: 'Foodophile',
                    imageUrl: 'https://a.slack-edge.com/66f9/img/avatars-teams/ava_0001-34.png'
                }}
                onMessageWasSent={this._onMessageWasSent}
                messageList={this.state.messageList}
                onFilesSelected={this._onFilesSelected}
                newMessagesCount={this.state.newMessagesCount}
                handleClick={this._handleClick}
                isOpen={this.state.isOpen}
                showEmoji
            />
        </div>)
    }

您必须在 class 组件中绑定 class 方法,以便使用 this 调用它们。但是你必须这样做,例如在构造函数中但不在您的渲染函数中!

查看此 very nice explanation,了解为什么以及如何绑定您的函数。

  constructor( props ){
    super( props );
    this._onMessageWasSent = this._onMessageWasSent.bind(this);
    this._onFilesSelected = this._onFilesSelected.bind(this);
    this._handleClick = this._handleClick.bind(this);
    this._sendMessage = this._sendMessage.bind(this);
  }

在您的渲染函数中,只需传递如下函数:

render() {
        return (<div>
            <Launcher
                agentProfile={{
                    teamName: 'Foodophile',
                    imageUrl: 'https://a.slack-edge.com/66f9/img/avatars-teams/ava_0001-34.png'
                }}
                onMessageWasSent={this._onMessageWasSent}
                messageList={this.state.messageList}
                onFilesSelected={this._onFilesSelected}
                newMessagesCount={this.state.newMessagesCount}
                handleClick={this._handleClick}
                isOpen={this.state.isOpen}
                showEmoji
            />
        </div>)
    }

另外,还有一个问题。 This 绑定在 JavaScript 中是一件棘手的事情,function()=>{} 箭头函数的处理方式不同。在您的情况下,只需使用箭头函数即可。

apigClient.invokeApi(pathParams, pathTemplate, method, additionalParams, body)
            .then((result) => {
                var text = result.data.body
                console.log(text)
                console.log(text.length)
                this._sendMessage(text)
            }).catch(function (result) {
            });

这将确保您的 then-callback 函数中的 this 仍然是您期望的 this。这就是为什么,如果您将所有函数(_onMessageWasSent_onMessageWasSent_onFilesSelectedhandleClick_sendMessage)重构为箭头函数,则没有必要不再在构造函数中将它们绑定到 this。

例如看这个:

_onMessageWasSent = (message) =>  {
   // your function body
}

您可能已经删除了行 this._onMessageWasSent = this._onMessageWasSent.bind(this);

w3school.

阅读有关此函数绑定的更多信息