假設有一個 list component 資料是透過 api 取得,本身 component 又可以編輯這個資料
class List extends Component {
constructor(props) {
super(props)
const { list } = props
this.state = { list }
this.getList() // API 取資料
}
render(){
const { list } = this.state
return list.map((d,i)=><input value={d.name} key={i} />)
}
}
為了在 component 中控制這些資料可以撰寫 componentDidUpdate
,把 API 的資料填入 state
做控制
componentDidUpdate(prevProps) {
this.setState({ list })
}
但是,因為本身 component 又要可以編寫這個資料,可能是以下這樣
<input value={d.name} key={i} onChange={e=>this.setState(...)} />
由於 onChange
中的 this.setState
會觸發 update ,但又不能每次 update 之後都去複寫 state
(就會造成兩難的情況)。
所以需先判斷 update 之前的 props.list
與 updat 之後的 props
相同,就不用再做複寫了
如果資料是 object 要做比對,可以安裝 immutable.js 來做深層 object 比對
const { Map, is } = require('immutable')
const map1 = Map({ a: 1, b: 1, c: 1 })
const map2 = Map({ a: 1, b: 1, c: 1 })
assert.equal(is(map1, map2), true)
但是這邊如果使用 redux 架構的時候,其實可以單純用 isfetching
的改變來修改,這時候無論是重新取得資料或 componet 內部自行修改資料,都可以正常 work
componentDidUpdate(prevProps) {
if (prevProps.isfetching && !this.props.isfetching)
this.setState({
list: this.props.list
})
}