React写出来的App虽然可以在浏览器上调用,但是一旦你刷新或者关闭页面,所有的数据都会被重置。那么如何在不调用后端服务器的情况下,将这些数据持久化呢?
Web Storage API可以为我们实现这项功能。Web Storage API,顾名思义给我们提供了一个让浏览器存储我们数据的接口。那么它具体是如何实现存储的呢?
存储的原理:Web Storage API包含了两种存储机制,sessionStorage和localStorage。
- sessionStorage 为每一个给定的源(given origin)维持一个独立的存储区域,该存储区域在页面会话期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复)。
- localStorage 同样的功能,但是在浏览器关闭,然后重新打开后数据仍然存在。
通俗的说,在我们使用sessionStorage或者localStorage时,浏览器会给我们划分一个存储我们数据的存储箱。在这个存储箱被创建之后,浏览器如何保证能够识别出我们的存储箱呢?现实生活中,每个存储箱都会有一个id,比如说A7、B11之类的,我们想要找到自己的存储箱的话,只要按照id找就可以了。在这个情况下,app的id就是我们的域名,浏览器通过找寻我们的域名就可以找到相应的存储箱。
在找到相应的存储箱之后,里面存储了两种数据,一种是通过sessionStorage存入的,另一种是通过localStorage存入的。那么这两种数据有什么区别呢?sessionStorage可以理解为短期数据,它的有效期是一次打开关闭浏览器的行为,只要页面处于开启状态下,短期数据就会一直存在,包括刷新。但是在每一次关闭浏览器之后,浏览器就会把存储箱里的短期数据清除。而localStorage可以理解为长期数据,存储箱会一直保留长期数据,直到存储箱被摧毁。
存储的是什么:在现实生活中,存储的东西是物品,而在web storage中,存储箱存储的是json字符串。
存储的方法:localStorage为我们提供了两个方法,用以实现数据的存储和调用(sessionStorage也是一样)。
- localStorage.setItem(key, value):已知我们存储的数据必须是一个Json字符串,那么就一定会有一个key和一个value。相应的,setItem方法有两个参数,第一个是key,第二个是value,浏览器会自动帮我们把传入的健值对编译成Json字符串。
- localStorage.getItem(key): 当我们需要把数据从存储箱中取出时,我们需要调用getItem方法。传入需要的key值,返回相应的value值。
在React中的应用:现在我们知道了数据持久化的原理,那么如何在我们的react app中去调用呢?一般来说,想要为一个react app实现数据的持久化,比较普遍的做法是,在更改state的时候给存储箱传入数据,在模块加载的时候,从存储箱取出之前存入的数据。本文中用一个表单的例子去举例说明:
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>
);
}
}
此时,表单中的数据不会被浏览器记住,因为我们还没有让浏览器为我们创建一个存储箱。
- 当点击Remember Me时,将userName存入存储箱:此时我们应该去编辑Remember Me的handleClick函数,在点击时去触发存储机制。
handleClick = () => {
//将userName从state中解构出来
const {userName} = this.state
//在每一次触发点击事件时,把userName数据存入localStorage
localStorage.setItem("userName", userName)
}
- 当加载组件时,从localStorage获取数据:
componentDidMount() {
const userName = localStorage.getItem("userName")
this.setState({userName: userName})
}
这样,即使将网页关闭,或者刷新页面,input框里的值都会保留着上一次更改的值,也就实现了数据的持久化。
本文的示例可以在表单示例源码中编辑。