React:使用本地存储持久化状态

React: Persisting State Using Local Storage

我正在编写一个应用程序,其中有一组评论,一个人可以回复评论,但每个评论只能有一个回复。到目前为止,我是通过在我的 ReviewCardDetails 组件中渲染 ReviewResponseBox 组件并将 review_id 作为道具传递来实现的。 我已经实现了这样的逻辑,一旦有一个 ReviewResponse,就不会再出现要写另一个的表单。然而,在我用一个空数组初始化这个组件的状态之前,所以当我刷新我的页面时,响应消失了,表单又回来了。 (现在注释掉了)

我试图通过使用 React LocalStorage 保留我的状态来解决这个问题,但是我在编写我的方法来执行此操作时遇到了问题。这是我目前所拥有的:

呈现 ReviewResponseBox 并将 review_id 作为 props 传递的组件:

import React from "react";
import './Review.css';
import { useLocation } from "react-router-dom";
import StarRatings from "react-star-ratings";
import ReviewResponseBox from "../ReviewResponse/ReviewResponseBox";

const ReviewCardDetails = () => {
  const location = useLocation();
  const { review } = location?.state; // ? - optional chaining

  console.log("history location details: ", location);
  return (
    <div key={review.id} className="card-deck">
      <div className="card">
        <div>
        <div className='card-container'>
          <h4 className="card-title">{review.place}</h4>
          <StarRatings
            rating={review.rating}
            starRatedColor="gold"
            starDimension="20px"
          />
          <div className="card-body">{review.content}</div>
          <div className="card-footer">
            {review.author} - {review.published_at}
          </div>
          </div>
        </div>
      </div>
      <br></br>
    <ReviewResponseBox review_id={review.id}/>
    </div>
  );
};

export default ReviewCardDetails;

我想要跟踪状态以便它可以呈现表单或响应的组件:

import React from 'react';
import ReviewResponse from './ReviewResponse';
import ReviewResponseForm from './ReviewResponseForm';
import { reactLocalStorage } from "reactjs-localstorage";

class ReviewResponseBox extends React.Component {
 // constructor() {
  //  super()

 //   this.state = {
  //    reviewResponses: []
  //  };
//  }

 fetchResponses = () => {
  let reviewResponses = [];
  localStorage.setResponses
  reviewResponses.push(reviewResponse);
}
  
  render () {
    const reviewResponses = this.getResponses();
    const reviewResponseNodes = <div className="reviewResponse-list">{reviewResponses}</div>;
   
    return(
      <div className="reviewResponse-box">
        {reviewResponses.length 
          ? (
            <>
              {reviewResponseNodes}
            </>
          )
          : (
            <ReviewResponseForm addResponse={this.addResponse.bind(this)}/>
          )}
      </div> 
        
    );
  } 
  

  addResponse(review_id, author, body) {
    const reviewResponse = {
      review_id,
      author,
      body
    };
    this.setState({ reviewResponses: this.state.reviewResponses.concat([reviewResponse]) }); // *new array references help React stay fast, so concat works better than push here.
  }
   
  
  
  getResponses() {    
    return this.state.reviewResponses.map((reviewResponse) => { 
      return (
        <ReviewResponse 
          author={reviewResponse.author} 
          body={reviewResponse.body} 
          review_id={this.state.review_id} />
      ); 
    });
  }

  
  
}
export default ReviewResponseBox;

任何指导将不胜感激

当使用 componentDidUpdate 生命周期方法更新状态时,您将保留对 localStorage 的响应。使用 componentDidMount 生命周期方法读取 localStorage 值并设置本地组件状态,或者由于从 localStorage 读取是同步的,直接设置初始状态。

我认为您也不需要单独的包来处理这个问题,您可以轻松地使用 localStorage API

import React from "react";
import ReviewResponse from "./ReviewResponse";
import ReviewResponseForm from "./ReviewResponseForm";

class ReviewResponseBox extends React.Component {
  state = {
    reviewResponses: JSON.parse(localStorage.getItem(`reviewResponses-${this.props.review_id}`)) || []
  };

  storageKey = () => `reviewResponses-${this.props.review_id}`;

  componentDidUpdate(prevProps, prevState) {
    if (prevState.reviewResponses !== this.state.reviewResponses) {
      localStorage.setItem(
        `reviewResponses-${this.props.review_id}`,
        JSON.stringify(this.state.reviewResponses)
      );
    }
  }

  render() {
    const reviewResponses = this.getResponses();
    const reviewResponseNodes = (
      <div className="reviewResponse-list">{reviewResponses}</div>
    );

    return (
      <div className="reviewResponse-box">
        {reviewResponses.length ? (
          <>{reviewResponseNodes}</>
        ) : (
          <ReviewResponseForm addResponse={this.addResponse.bind(this)} />
        )}
      </div>
    );
  }

  addResponse(review_id, author, body) {
    const reviewResponse = {
      review_id,
      author,
      body
    };
    this.setState({
      reviewResponses: this.state.reviewResponses.concat([reviewResponse])
    }); // *new array references help React stay fast, so concat works better than push here.
  }

  getResponses() {
    return this.state.reviewResponses.map((reviewResponse) => {
      return (
        <ReviewResponse
          author={reviewResponse.author}
          body={reviewResponse.body}
          review_id={this.state.review_id}
        />
      );
    });
  }
}