本文原创地址链接: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%'">