learn from 《React全家桶:前端开发与实例详解》 https://zh-hans.reactjs.org/tutorial/tutorial.html https://zh-hans.reactjs.org/docs/create-a-new-react-app.html#create-react-app
服务器负责持久化数据,React app 数据持久化于 data.json 文件中
书籍作者准备好了一个本地服务器 server.js (里面有一些 api 如 http://localhost:3000/api/timers
可以调用),data.json 数据
使用 api 测试软件,get http://localhost:3000/api/timers
[
{
"title": "Mow the lawn",
"project": "House Chores",
"elapsed": 5458797,
"id": "0a4a79cb-b06d-4cb1-883d-549a1e3b66d7",
"runningSince": null
},
{
"title": "Clear paper jam",
"project": "Office Chores",
"elapsed": 1274709,
"id": "a73c1d19-f32d-4aff-b470-cea4e792406a",
"runningSince": null
},
{
"title": "Ponder origins of universe",
"project": "Life Chores",
"id": "2c43306e-5b44-4ff8-8753-33c35adbd06f",
"elapsed": 11750,
"runningSince": 1456225941911
}
]
作者给我们提供了 client.js 现在我们要从服务器获取 Timers 的配置
错误写法: const timers = client.getTimers()
,网络请求是 异步(防止 IO 阻塞) 的,被调用的函数本身不会返回有用的值
可以:传递一个函数进去,如果服务器成功返回结果,getTimers()
将在服务器返回消息后,调用传入的这个函数
client.getTimers((serverTimers) => ( // do something use serverTimers ))
从服务器获取配置,每 5 秒刷新一下
class TimersDashBoard extends React.Component {
state = {
timers: []
}
componentDidMount() {
this.loadTimersFromServer();
setInterval(this.loadTimersFromServer, 5000);
}
loadTimersFromServer = () => {
client.getTimers((serverTimers) => (
this.setState({timers: serverTimers})
))
}
...
期间报错了:
SyntaxError: Unexpected token ] in JSON at position 602
at JSON.parse (<anonymous>)
at D:/gitcode/react/time_tracking_app/server.js:27:19
报错是因为 json 文件格式问题 [{}, {}, {}, ]
最后一个 {}
后面不能跟 ,
不论你做什么,5 秒后肯定被服务器重置
如果你在客户端对服务器做了更新,他能同步到其他客户端(比如电商的库存数量)
startTimer = (timerId) => {
const now = Date.now();
this.setState({
timers: this.state.timers.map((t) => {
if(t.id === timerId) {
return Object.assign({}, t, {
runningSince: now
})
}
else{
return t
}
})
})
client.startTimer({
id: timerId,
start: now
})
}
stopTimer = (timerId) => {
const now = Date.now();
this.setState({
timers: this.state.timers.map((t) => {
if(t.id === timerId) {
const lastElapsed = now - t.runningSince;
return Object.assign({}, t, {
elapsed: lastElapsed + t.elapsed,
runningSince: null
})
}
else{
return t
}
})
})
client.stopTimer({
id: timerId, stop: now
})
}
createTimer = (timer) => {
const t = helpers.newTimer(timer);
this.setState({
timers: this.state.timers.concat(t)
})
client.createTimer(t)
}
deleteTimer = (timerId) => {
this.setState({
timers: this.state.timers.filter(t => t.id !== timerId),
})
client.deleteTimer({id: timerId})
}
updateTimer = (attrs) => {
this.setState({
timers: this.state.timers.map((timer) => {
if (timer.id === attrs.id) {
return Object.assign({}, timer, {
title: attrs.title,
project: attrs.project
})
}
else{
return timer;
}
})
})
client.updateTimer(attrs)
}
现在所有的操作都会持久化到服务器,并且在不同的选项卡中同步