【问题标题】:Persisting data without redux-persist or localStorage在没有 redux-persist 或 localStorage 的情况下持久化数据
【发布时间】:2020-02-03 09:53:34
【问题描述】:

所以,我又一次遇到了持久化状态树的问题。在登录时,为了让用户持久存在,我从我的主 App.js 中分派了一个操作,并获得了当前登录的用户,如下所示:

App.js

componentDidMount() {
    const authToken = localStorage.getItem("authToken")

    if (authToken) {
        this.props.dispatch({ type: "TOKEN_VERIFICATION_STARTS" })
        this.props.dispatch(getCurrentUser(authToken))
    }
}

现在,我有一个表单,当它被提交时,我会将用户重定向到提要,在那里我将以卡片形式显示帖子标题和描述。但像往常一样,postData 在刷新后消失了。

这意味着我是否必须创建另一个路由,类似于我为获取当前登录用户而创建的 /me 路由?并再次从 App.js 中的 componentDidMount() 派发一个动作?

NewPostForm.js

import React, { Component } from "react"
import { connect } from "react-redux"
import { addpost } from "../actions/userActions"

class NewpostForm extends Component {

    constructor(props) {
        super(props)
        this.state = {
            postTitle: "",
            postDescription: "",
            maxLength: 140
        }
    }

    handleChange = (event) => {
        const { name, value } = event.target
        this.setState({
            [name]: value
        })
    }

    handleSubmit = () => {
        const postData = this.state
        this.props.dispatch(addpost(postData, () => {
            this.props.history.push("/feed")
        })
      )
    }

    render() {
        const charactersRemaining = (this.state.maxLength - this.state.postDescription.length)
        return (
            <div>
                <input
                    onChange={this.handleChange}
                    name="postTitle"
                    value={this.state.postTitle}
                    className="input"
                    placeholder="Title"
                    maxLength="100"
                />

                <textarea
                    onChange={this.handleChange}
                    name="postDescription"
                    value={this.state.postDescription}
                    className="textarea"
                    maxLength="140">
                </textarea>
                <button onClick={this.handleSubmit}>Submit</button>

                <div>
                    Characters remaining: {charactersRemaining}
                </div>

            </div>
        )
    }
}

const mapStateToProps = (store) => {
    return store
}


export default connect(mapStateToProps)(NewpostForm)

addPost 操作

export const addpost = (postData, redirect) => {
    console.log("inside addpost action")
    return async dispatch => {
        dispatch({
            type: "ADD_post_STARTS"
        })
        try {
            const res = await axios.post("http://localhost:3000/api/v1/posts/new", postData, {
                headers: {
                    "Content-Type": "application/json",
                    "Authorization": `${localStorage.authToken}`
                }
            })
            dispatch({
                type: "ADD_post_SUCCESS",
                data: { post: res.data.post },
            })
            redirect()
        } catch (err) {
            dispatch({
                type: "ADD_post_ERROR",
                data: { error: "Something went wrong" }
            })
        }

    }
}

Feed.js

import React from "react";
import { connect } from "react-redux";

const Feed = (props) => {
  // const postTitle = (props.post && props.post.post.post.postTitle)
  return (
    <div className="card">
      <header className="card-header">
        <p className="card-header-title">
          {/* {postTitle} */}
        </p>
      </header>
      <div className="card-content">
        <div className="content">
          The text of the post written by the user.
        </div>
      </div>
      <footer className="card-footer">
        <a href="#" className="card-footer-item">
          Edit
        </a>
        <a href="#" className="card-footer-item">
          Delete
        </a>
      </footer>
    </div>
  );
};

const mapStateToProps = state => {
  return state;
};

export default connect(mapStateToProps)(Feed);

【问题讨论】:

  • @FMCorz 据我所知 localStorage.getItem 是一个同步函数
  • 我的问题是如何在刷新时保留帖子数据,例如当我第一次将用户重定向到提要时,所有内容都会显示 - 帖子标题、描述等,但在刷新时,它不会。
  • @DanielB。你是对的!我删除了我的评论。
  • 您能添加您的“/feed”组件代码吗?
  • 添加了 Feed 组件。 @Niraj

标签: reactjs redux react-redux


【解决方案1】:

我知道你想要没有 redux-persist 但 redux 正常行为会强制从头开始重新初始化存储。如果你想保持你的状态甚至刷新你的页面,我会推荐以下包:

https://github.com/rt2zz/redux-persist

如果您在页面重定向上丢失状态或使用 react-router 前往不同的路线,您将需要使用:

https://github.com/reactjs/react-router-redux

【讨论】:

    【解决方案2】:

    如果我理解正确,您似乎在您的提要页面中使用/api/v1/posts/new 的响应,但尝试访问 NewPostForm.js

    的本地状态
    this.state = {
       postTitle: "",
       postDescription: "",
       maxLength: 140
    }
    

    您可能需要将数据保存到 redux 存储,以便可以在不同的路由之间共享,而不是使用本地状态来保存无法共享到另一个组件的表单数据(除非作为 props 传递,这不是这里的情况) /p>

     handleChange = (event) => {
       const { dispatch } = this.props;
       const { name, value } = event.target;
       dispatch(setPostData(name, value));
     }
    

    您的操作可能如下所示:-

    export const setPostData = (name, value) => ({
         type: "SET_POST_DATA",
         name,
         value,
    });
    

    之后,您可以在 Feed 页面上使用 this.props.postTitle

    编辑:为了在页面重新加载(完全浏览器重新加载)之间保持状态,您可能需要获取挂载上的所有数据(高阶组件很有帮助)或使用本地存储。

    【讨论】:

    • @metalHeadDev 刚刚看到您对刷新问题的评论,您的意思是完全浏览器刷新(网页重新加载)。
    • 你的意思是我问的另一个问题吗?
    • 这不会从 redux 商店中消失吗?我们如何在 handleChange 上调度一个动作?
    • 是的,它会消失,简而言之,您可以通过在每次重新加载时调用每个端点或将数据存储在本地存储中,然后在重新加载时使用本地存储初始化存储来解决它。将数据存储到本地存储似乎成本更低,因为不会有获取延迟。
    • 您可能需要在使用本地存储时进行上述更改,以便提要页面所需的所有数据都有足够的数据加载。此外,我建议保存当前路线信息。最好使用 github.com/supasate/connected-react-router 而不是 react-router-redux,因为这个包已被弃用。
    猜你喜欢
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 2021-03-24
    • 2018-08-14
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 2022-11-11
    相关资源
    最近更新 更多