简体   繁体   中英

How to listen to localstorage in react.js

I'm having a problem with a component that gets data from an array in localstorage. It gets the initial data when the page loads, but how do I update when localstorage is changed?

import React, {Component} from 'react'; 
    class MovieList extends Component {
       constructor(props){
          super(props)
            this.state = {
            filmList: []     
          }
       }    
      componentWillMount(){
          var film = [],
          keys = Object.keys(localStorage),
          i = keys.length;
          while ( i-- ) {
             film.push( localStorage.getItem(keys[i]))     
          }
          this.setState({filmList: film})

      };

      render(){
        return(
           <ul>
              <li>{this.state.filmlist}</li>            
           </ul>

        );
    }

}

export default MovieList;

Per Mozilla's Web API docs there's a StorageEvent that gets fired whenever a change is made to the Storage object.

I created an Alert component within my application that would go off whenever a change was made to a specific localStorage item. I would've added a code snippet for you to run but you can't access localStorage through it due to cross-origin issues.

class Alert extends React.Component {
    constructor(props) {
        super(props)
        this.agree = this.agree.bind(this)
        this.disagree = this.disagree.bind(this)
        this.localStorageUpdated = this.localStorageUpdated.bind(this)
        this.state = {
            status: null
        }
    }
    componentDidMount() {
        if (typeof window !== 'undefined') {
            this.setState({status: localStorage.getItem('localstorage-status') ? true : false})

            window.addEventListener('storage', this.localStorageUpdated)
        }
    }
    componentWillUnmount(){
        if (typeof window !== 'undefined') {
            window.removeEventListener('storage', this.localStorageUpdated)
        }
    }
    agree(){
        localStorage.setItem('localstorage-status', true)
        this.updateState(true)
    }
    disagree(){
        localStorage.setItem('localstorage-status', false)
        this.updateState(false)
    }
    localStorageUpdated(){
        if (!localStorage.getItem('localstorage-status')) {
            this.updateState(false)
        } 
        else if (!this.state.status) {
            this.updateState(true)
        }
    }
    updateState(value){
        this.setState({status:value})
    }
    render () {
        return( !this.state.status ? 
            <div class="alert-wrapper">
                <h3>The Good Stuff</h3>
                <p>Blah blah blah</p>
                <div class="alert-button-wrap">
                    <button onClick={this.disagree}>Disagree</button>
                    <button onClick={this.agree}>Agree</button>
                </div>
            </div>
         : null )
    }
}

对于任何绊倒这个问题的人,可以在这里找到“如何收听localStorage更改”的答案: https//developer.mozilla.org/en-US/docs/Web/API/StorageEvent

import React, { Component } from "react";
import { Subject, share } from "rxjs";

export default class StorageService extends Component {
  constructor() {
    super();
    this.start();
    this.onSubject = new Subject();
    this.changes = this.onSubject.asObservable().pipe(share());
  }

  componentWillUnmount() {
    this.stop();
  }

  getStorage() {
    let s = [];
    for (let i = 0; i < localStorage.length; i++) {
      s.push({
        key: localStorage.key(i),
        value: JSON.parse(localStorage.getItem(localStorage.key(i))),
      });
    }
    return s;
  }

  store(key, data) {
    localStorage.setItem(key, JSON.stringify(data));
    this.onSubject.next({ key: key, value: data });
  }

  clear(key) {
    localStorage.removeItem(key);
    this.onSubject.next({ key: key, value: null });
  }

  start() {
    window.addEventListener("storage", this.storageEventListener.bind(this));
  }

  storageEventListener(event) {
    if (event.storageArea === localStorage) {
      let v;
      try {
        v = JSON.parse(event.newValue);
      } catch (e) {
        v = event.newValue;
      }
      this.onSubject.next({ key: event.key, value: v });
    }
  }

  stop() {
    window.removeEventListener("storage", this.storageEventListener.bind(this));
    this.onSubject.complete();
  }

  render() {
    return <div>StorageService</div>;
  }
}

// import it where you needed and subscribe


const newStorageService = new StorageService();
newStorageService.changes.subscribe((localStoreObject) => {
    // do whatever yo want 
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM