簡體   English   中英

Redux、localStorage 和 React:刷新頁面時出錯

[英]Redux, localStorage, and React: Getting an error when refreshing my page

我的目標是通過刷新保持我的 React 狀態。 我已經在教程中看到它使用瀏覽器的localStorage完成的(如果你想看,只需點擊那里)。 我想使用該解決方案,因為相對於淘汰 Redux Persist 而言,它看起來很簡單。

預期的結果是一個像以前一樣刷新和重新加載的頁面。 相反,我收到一個錯誤。 我懷疑錯誤發生是因為 Redux 狀態卸載(?),然后我的代碼嘗試將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);

post.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 但我認為它不相關。

我對我的代碼和錯誤的爭論是,好吧,我認為我的代碼應該可以工作! 首先我調用localStorage.setItem("state", this.props.posts); 在我的 componentDidMount() 方法中,用我的帖子狀態變量的內容設置我的 localStorage。 然后當頁面重新加載時,我的構造函數方法 - 在組件生命周期中的任何其他代碼之前首先觸發!!! -- 調用this.props.returnPostsToState(stateFromStorage); ,從而使用“state From Storage”的內容重置全局Redux狀態,這是我原來的帖子內容!

我究竟做錯了什么?

我不知道如何實現它,但是,我認為有一些if (stateHasReloaded) { const threadTitle = this.props.posts[number].title; }解決方案,“ if (stateHasReloaded) { const threadTitle = this.props.posts[number].title; } ”我只是不確切地知道它的樣子。

在此先感謝您的幫助

我認為當您從本地存儲獲取數據時,它將是字符串,因此之后您的組件將無法解析它。嘗試從本地存儲獲取數據時解析數據。

 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:'';

讓我看看它是否有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM