本文原創位址連結: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%'">