嗨嗨!大家好啊!今天來輕鬆一點點(其實每天都不太難啦XD),昨天已經能將資料用迴圈寫進組件輸出到畫面上了!接下來我們來展開資料的編輯畫面!這篇會採組件重用的邏輯來做到這件事情,那進入正文吧!
首先看一下資料編輯的畫面:
是不是覺得有點熟悉?沒錯!他就跟新增時的畫面一模一樣!所以我們也不需要再重新做一個組件了,直接使用之前做的InputTask
就好,那要改的時候先打開昨天製作的List.jsx
檔案,我們需要在裡面加上的東西有幾點:
List
上設定點擊事件,點擊後可以將InputTask
渲染出來。List
接收到的待辦事項資料經由props
傳到InputTask
中。為了第三點的到來,就趕緊開工吧XD,一起打開List.jsx
:
state
中多新增一個屬性,幫我們保管要輸出的InputTask
組件內容:
constructor(props) {
super(props)
this.changeState = this.changeState.bind(this)
this.list = React.createRef()
this.state = {important:this.props.listData.important
,complete:this.props.listData.complete
,editTasks:null}
}
這樣子我們在render
的時候就能夠固定輸出他,什麼意思呢?看下去吧!render
中輸出剛剛的this.state.editTasks
內的值,因為他平常是null,所以一直待著也不會有什麼影響:
render() {
//初始化組件
return (
<div class="listBlock">
<div class={' list ' +
(this.state.important == 'Y' ? ' important ' : '')}>
{/*因為怕太長所以中間省略*/}
</div>
{/*在這裡固定輸出this.state.editTasks*/}
<div>
{this.state.editTasks}
</div>
</div>
)
}
InputTask
組件寫到this.state.editTasks
中,所以新增以下事件設定this.state.editTasks
的值,並同時把待辦事項的資料給InputTask
:
openEdit() {
this.setState({editTasks:(<InputTask listData={this.props.listData} />)})
}
既然有打開那也有關閉,等等要把關閉用props
傳給InputTask
的closeAdd
中,記得我們很久很久之前有寫過這個吧XD
closeEdit() {
this.setState({editTasks:null})
}
搞定後記得把他傳進InputTask
中,所以把上方的openEdit
改成下面這樣:
openEdit(event) {
this.setState({editTasks:(<InputTask closeAdd={this.closeEdit}
listData={this.props.listData} />)})
}
記得把openEdit
設定給List
組件的點擊事件:
render() {
//初始化組件
return (
<div class="listBlock">
<div class={' list ' +
(this.state.important == 'Y' ? ' important ' : '')}
onClick={this.openEdit}>
{/*因為怕太長所以中間省略*/}
</div>
</div>
)
}
InputTask.jsx
做一些小調整,其實沒有太複雜,就只是因為當初在這裡預設state
的值全都是空的,但現在不同了,有可能我會接收到從外面傳進來的值,所以在這種情況下我們得在設定state
時做一些小調整:
constructor(props) {
super(props)
//如果有值的話就寫入值,沒值就預設都空的
if (this.props.listData) {
this.state = this.props.listData
}
else {
this.state = { id: '', name: '', date: '', time: '', file: ''
, commit: '', important: '', complete: false }
}
}
就是上方簡簡單單的調整,那執行來看看吧!
登愣!野生的Bug出現了!當我點下List
的任何一處後,雖然編輯畫面跳出來了,但是List
本身卻沒有消失:
而且當我只是單純要將它變成已完成或標記重要時,他依然會開啟編輯畫面,總之這兩個問題我們一個一個解決!
List
可以在點擊後隱藏,就必須要可以先抓到那個div
,但是在組件可以重複使用的狀況下,通常不會為組件內的DOM
設定id
,否則當組件重用時,就只會有第一個設定id
的生效而已,那該怎麼辦呢?就用ref
吧!
List
的constructor
內createRef()
this.list = React.createRef()
ref
給點擊後需隱藏的div
:
render() {
//初始化組件
return (
<div class="listBlock">
<div class={' list ' +
(this.state.important == 'Y' ? ' important ' : '')}
onClick={this.openEdit}
ref={this.list}>
{/*中間省略*/}
</div>
{/*下面雖然不長但也省略*/}
</div>
)
}
openEdit
和closeEdit
兩個事件,當點擊打開時就為他的CSS
增加display=none
做隱藏,關閉時再把display
的none
拿掉讓他顯示:
openEdit() {
this.list.current.style.display = 'none'
this.setState({editTasks:(<InputTask closeAdd={this.closeEdit}
listData={this.props.listData} />)})
}
closeEdit() {
this.list.current.style.display = ''
this.setState({editTasks:null})
}
openEdit
,這個其實很簡單,只需要去判斷觸發openEdit
事件的元件是什麼就好,那問題來了,該怎麼知道呢?就決定是你了!event
!從event
判斷如果class
不含fa-star
和taskChk
才顯示編輯畫面:
openEdit(event) {
if (event.target.className.indexOf('fa-star') === -1 &&
event.target.className.indexOf('taskChk') === -1) {
this.list.current.style.display = 'none'
this.setState({editTasks:(<InputTask closeAdd={this.closeEdit}
listData={this.props.listData} />)})
}
}
處理完上面兩個Bug後就能重新執行網頁了!這時候大家的頁面應該不只可以新增,還能夠透過點擊待辦事項的列表顯示詳細資料!只是目前+ SAVE
這個按鈕的事件還是新增,明天我們再來將修改資料的事件寫好!讓他能夠再InputTask
中修改待辦事項的資料!那以下附上今天進度的GitHub
連結:
GitHub程式目錄連結
GitPage頁面連結
到這裡其實會發現,在實作的時候都一一用上前20篇學的所有精華(算精華嗎XD),最後這個作品就算是一個總複習,讓大家也讓我更熟悉組件的開發模式!那最後還是感謝各位大大的觀看,如果文章中有任何問題或是錯誤的地方,還麻煩留言告所我,小弟都會盡快查看並修改或補充文章內容的!謝謝大家