天天看點

React實作聊天機器人

本文原創位址連結:http://blog.csdn.net/zhou_xiao_cheng/article/details/52512434,未經部落客允許不得轉載。

用React實作了一個聊天機器人,結合使用fetch工具對網絡資料進行讀取,這些資料由圖靈API提供。

前期工作

需要注冊一個圖靈帳号(http://www.tuling123.com/),然後建立機器人,拿到API位址及APIkey,就OK了。

廢話不多說,一起來看代碼:

class FetchDemo extends React.Component {
  //構造函數中初始化狀态值,meg:輸入的值,respon:機器人傳回值,megArray:使用者發送的值
  constructor() {
    super()
    this.state = {
      meg: '',
      respon: [],
      megArray: []
    }
  }
  //input的onChange綁定事件
  handleData(e) {
    this.setState({
      meg: e.target.value
    })
  }
  //自定義函數,處理發送資料及傳回的網絡資料的儲存操作
  sendMessage() {
    var message = this.state.meg
    if(message === ''){
      alert('不能發送空白消息哦')
    }else{
          this.setState({
      megArray: [...this.state.megArray, message]
    })
    //鎖定目前環境
    var that = this
    //使用fetch工具
    var func = fetch('http://www.tuling123.com/openapi/api?key=f0d11b6cae4647b2bd810a6a3df2136f&info=' + message, {
      method: 'POST',
      type: 'cors'
    }).then(function(response) {
      return response.json()
    }).then(function(detail) {
      return (that.setState({
        respon: [...that.state.respon, detail.text]
      }, () => {
        //ReactDOM.findDOMNode()找到真正的節點
        var el = ReactDOM.findDOMNode(that.refs.msgList);
        el.scrollTop = el.scrollHeight;
      }))
    })
    this.state.meg = ''
    }
  }

  render() {
    var meg = this.state.meg
    var megArray = this.state.megArray
    var respon = this.state.respon

    return (
      <div className="content">
        //ref的使用
        <div className="msg-list" ref="msgList">
          {megArray.map((elem,index) => (
            <div className="container" key={index}>
              <div className="message">{elem}</div>
              <div className="response">{respon[index]}</div>
            </div>)
           )}
        </div>
         <div className="fixedBottom">
           <input className="input" value={meg} onChange={this.handleData.bind(this)} />
           <button className="button" onClick={this.sendMessage.bind(this)}>發送</button>
         </div>
      </div>
    )
  }
}

ReactDOM.render(<FetchDemo />, document.getElementById('app'))
           

以上代碼的實作都是比較簡單的,需要特别說明的是refs,它的使用方法如下:

class Demo extends React.Component {
  method() {
    ReactDOM.findDOMNode(this.refs.refName);
  }
  render() {
    return (
      <div ref="refName"/>
    )
  }
}
           

這是因為,在React中,為了安全(防止XCC等),一個元件類中的

render()

方法傳回的其實并不是真正的DOM(是以

render()

裡面的

<div />

也不是真正的DOM節點),它傳回的是一棵最終會渲染成HTML的React元件樹。那麼,當你需要在某個DOM節點做什麼的時候,就郁悶了。。。

但是,機智的facebook已經幫你想好解決方法啦,那就是使用refs。在

render()

方法中,你可以像上面一樣,在标簽(如

<div />

等)及元件裡使用ref對這個标簽或元件進行定位,接着,在元件類定義的方法裡,使用

ReactDOM.findDOMNode(this.refs.refName)

就可以拿到已經渲染成HTML、且被定位了的該節點,然後,你想在該節點做什麼(額,剩下就是你自己的事了)。。。

其次,在Demo中,我們使用的fetch工具傳回的是一個Promise對象,不了解的可以戳阮兄-Promise對象。

好啦,大公告成,效果如下(發送消息按鈕被RERUN遮得差不多了,郁悶…要和小機器人聊天的話,一定不要戳錯按鈕哦):

height="585" scrolling="no" src="//codepen.io/zhouxiaocheng/embed/rrVXJm/?height=585&theme-id=0&default-tab=js,result&embed-version=2" allowfullscreen="true" width="100%'">&#10;

繼續閱讀