React寫出來的App雖然可以在瀏覽器上調(diào)用,但是一旦你刷新或者關(guān)閉頁面,所有的數(shù)據(jù)都會被重置。那么如何在不調(diào)用后端服務器的情況下,將這些數(shù)據(jù)持久化呢?
Web Storage API可以為我們實現(xiàn)這項功能。Web Storage API,顧名思義給我們提供了一個讓瀏覽器存儲我們數(shù)據(jù)的接口。那么它具體是如何實現(xiàn)存儲的呢?
存儲的原理:Web Storage API包含了兩種存儲機制,sessionStorage和localStorage。
- sessionStorage 為每一個給定的源(given origin)維持一個獨立的存儲區(qū)域,該存儲區(qū)域在頁面會話期間可用(即只要瀏覽器處于打開狀態(tài),包括頁面重新加載和恢復)。
- localStorage 同樣的功能,但是在瀏覽器關(guān)閉,然后重新打開后數(shù)據(jù)仍然存在。
通俗的說,在我們使用sessionStorage或者localStorage時,瀏覽器會給我們劃分一個存儲我們數(shù)據(jù)的存儲箱。在這個存儲箱被創(chuàng)建之后,瀏覽器如何保證能夠識別出我們的存儲箱呢?現(xiàn)實生活中,每個存儲箱都會有一個id,比如說A7、B11之類的,我們想要找到自己的存儲箱的話,只要按照id找就可以了。在這個情況下,app的id就是我們的域名,瀏覽器通過找尋我們的域名就可以找到相應的存儲箱。
在找到相應的存儲箱之后,里面存儲了兩種數(shù)據(jù),一種是通過sessionStorage存入的,另一種是通過localStorage存入的。那么這兩種數(shù)據(jù)有什么區(qū)別呢?sessionStorage可以理解為短期數(shù)據(jù),它的有效期是一次打開關(guān)閉瀏覽器的行為,只要頁面處于開啟狀態(tài)下,短期數(shù)據(jù)就會一直存在,包括刷新。但是在每一次關(guān)閉瀏覽器之后,瀏覽器就會把存儲箱里的短期數(shù)據(jù)清除。而localStorage可以理解為長期數(shù)據(jù),存儲箱會一直保留長期數(shù)據(jù),直到存儲箱被摧毀。
存儲的是什么:在現(xiàn)實生活中,存儲的東西是物品,而在web storage中,存儲箱存儲的是json字符串。
存儲的方法:localStorage為我們提供了兩個方法,用以實現(xiàn)數(shù)據(jù)的存儲和調(diào)用(sessionStorage也是一樣)。
- localStorage.setItem(key, value):已知我們存儲的數(shù)據(jù)必須是一個Json字符串,那么就一定會有一個key和一個value。相應的,setItem方法有兩個參數(shù),第一個是key,第二個是value,瀏覽器會自動幫我們把傳入的健值對編譯成Json字符串。
- localStorage.getItem(key): 當我們需要把數(shù)據(jù)從存儲箱中取出時,我們需要調(diào)用getItem方法。傳入需要的key值,返回相應的value值。
在React中的應用:現(xiàn)在我們知道了數(shù)據(jù)持久化的原理,那么如何在我們的react app中去調(diào)用呢?一般來說,想要為一個react app實現(xiàn)數(shù)據(jù)的持久化,比較普遍的做法是,在更改state的時候給存儲箱傳入數(shù)據(jù),在模塊加載的時候,從存儲箱取出之前存入的數(shù)據(jù)。本文中用一個表單的例子去舉例說明:

export default class App extends Component {
state = {
userName: ''
}
handleChange = (event) => {
const value = event.target.value
this.setState({userName: value})
}
handleClick = () => {
}
render() {
return (
<div className="App">
<label>userName: </label>
<input type="text" onChange={this.handleChange} value={this.state.userName} />
<button type="submit" onClick={this.handleClick}>Remember Me</button>
</div>
);
}
}
此時,表單中的數(shù)據(jù)不會被瀏覽器記住,因為我們還沒有讓瀏覽器為我們創(chuàng)建一個存儲箱。
- 當點擊Remember Me時,將userName存入存儲箱:此時我們應該去編輯Remember Me的handleClick函數(shù),在點擊時去觸發(fā)存儲機制。
handleClick = () => {
//將userName從state中解構(gòu)出來
const {userName} = this.state
//在每一次觸發(fā)點擊事件時,把userName數(shù)據(jù)存入localStorage
localStorage.setItem("userName", userName)
}
- 當加載組件時,從localStorage獲取數(shù)據(jù):
componentDidMount() {
const userName = localStorage.getItem("userName")
this.setState({userName: userName})
}
這樣,即使將網(wǎng)頁關(guān)閉,或者刷新頁面,input框里的值都會保留著上一次更改的值,也就實現(xiàn)了數(shù)據(jù)的持久化。
本文的示例可以在表單示例源碼中編輯。