天天看点

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;

继续阅读