我的目标是通过刷新使我的React状态保持不变。我使用浏览器的localStorage
seen it done in a tutorial(如果您想查看的话,只需在附近单击即可)。我想使用该解决方案,因为相对于淘汰Redux Persist而言,它看起来很简单。
预期结果是页面将像以前一样刷新并重新加载。相反,我得到一个错误。我怀疑错误是由于Redux状态unloads(?)而发生的,然后我的代码尝试将const threadTitle
指向this.props.posts[number]
中的状态,这当然不存在,因为刷新只是将其卸载了。
我得到的错误如下:
TypeError: Cannot read property 'title' of undefined
fullThread.render
C:/Users/Roland/React_apps/reddit-knockoff/src/FullThread/FullThread.js:30
27 |
28 | // deliberate exclusion of 2nd parameter in .slice() to make it go til the end
29 | const number = this.props.location.pathname.slice(1);
> 30 | const threadTitle = this.props.posts[number].title;
| ^ 31 | let flair = null;
32 | const upVotes = this.props.posts[number].upvotes;
33 | const author = this.props.posts[number].author;
到目前为止,我已经尝试观看教程视频并突击Google的StackOverflow结果,以获取有关如何使用localStorage解决问题的提示。我已经启动并运行了一些代码,但这还不够。看看:
FullThread.js,错误消息指向该位置。
import React, { Component } from "react";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
class fullThread extends Component {
constructor(props) {
super(props);
const stateFromStorage = localStorage.getItem("state");
if (this.props.posts === null) {
this.props.returnPostsToState(stateFromStorage);
}
}
componentDidMount() {
localStorage.setItem("state", this.props.posts);
}
render() {
// deliberate exclusion of 2nd parameter in .slice() to make it go til the end
const number = this.props.location.pathname.slice(1);
const threadTitle = this.props.posts[number].title;
const upVotes = this.props.posts[number].upvotes;
const author = this.props.posts[number].author;
const age = this.props.posts[number].age;
const postText = this.props.posts[number].postText;
return (
<div>
<div className="MainBody">
<h4>Thread titled: {threadTitle}</h4>
<p>Removed content. The constants threadTitle, upVotes, author, age and postText go here</p>
</div>
</div>
);
}
}
const mapDispatchToProps = dispatch => {
return {
returnPostsToState: stateFromStorage =>
dispatch({ type: "RETURN", payload: stateFromStorage })
};
};
const mapStateToProps = state => {
return {
posts: state.posts
};
};
export default connect(mapStateToProps, mapDispatchToProps)(fullThread);
posts.js,其中包含我的Reducer
const initialPosts = {
posts: [
{
id: 0,
upvotes: 831,
flair: null,
title: "New? READ ME FIRST!",
author: "michael0x2a",
age: "2 years",
comments: 15,
postText:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
}
],
loggedIn: false
};
const reducer = (state = initialPosts, action) => {
if (action.type === "ADD_POST") {
console.log("HEY: ", action.newPost);
console.log(state.posts.concat(action.newPost.post.tempThread));
return {
...state,
// receives newPost data from app.js
posts: state.posts.concat(action.newPost.post.tempThread)
};
}
if (action.type === "RETURN") {
console.log("RETURNED! ", action.payload);
console.log("RETURNED: ", state.posts);
return {
...state,
posts: state.posts.concat(action.payload)
};
}
return state;
};
export default reducer;
我会发布app.js,但我认为这不相关。
我对代码和错误的争论是,嗯,我认为我的代码应该可以正常工作!首先,我在我的componentDidMount()方法中调用localStorage.setItem("state", this.props.posts);
以使用我的posts状态变量的内容设置我的localStorage。然后,当页面重新加载时,我的构造方法-在组件生命周期中的任何其他代码之前首先触发! -调用this.props.returnPostsToState(stateFromStorage);
,从而使用“ state From Storage”的内容重置全局Redux状态,这是我的原始帖子内容!
我在做什么错了?
我不知道如何实现它,但是,我认为有一些可行的解决方案,“ if (stateHasReloaded) { const threadTitle = this.props.posts[number].title; }
”我还不完全知道它的外观。
在此先感谢您的帮助
答案 0 :(得分:1)
我认为,当您从本地存储中获取数据时,它将是字符串,因此之后您的组件将无法对其进行解析。请尝试从本地存储中获取数据。
if (this.props.posts === null) {
this.props.returnPostsToState(JSON.parse(stateFromStorage));
}
另外,当您存储到本地存储时,请将数据字符串化为:
componentDidMount() {
localStorage.setItem("state", JSON.stringify(this.props.posts));
}
为了安全起见,您总是可以检查数据是否存在,因为您是从url获取号码的,因此任何人都可以将其更改为帖子没有的号码:
const threadTitle = this.props.posts[number]?this.props.posts[number].title:'';
让我看看它是否正在工作。