如何基于链接到本地​​存储的数组中的更改调用函数

时间:2019-06-12 12:03:17

标签: javascript reactjs

我所有的组件都在名为App的主类中。我想在数组showData更改时从Table组件调用函数persons。当我创建新表单并提交表单时,组件persons中也称为Form的数组会更改,该数组会自动与本地存储同步,从而导致数组persons中的更改组件Table。因此,我希望每次提交某些东西时都会调用函数showData并更新表。

应用组件

import React from 'react';
import './App.css';
import Form from './Form';
import Table from './Table'


class App extends React.Component {

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <Form />
          <Table />
        </header>
      </div>
    );
  }

}
export default App;

表组件

import React from 'react';
import styles from './styles.css';

let persons = [];


if (JSON.parse(localStorage.getItem("personsForms")) !== null)
    persons = JSON.parse(localStorage.getItem("personsForms"));


class Table extends React.Component {

    render() {
        return (
            <table className="myTable" id="editableTable">
                <thead>
                    <tr>
                        <th>Firstname</th>
                        <th>Lastname</th>
                        <th>Date Of Birthday</th>
                        <th>Salary</th>
                        <th>Favorite Choclates</th>
                        <th>Gender</th>
                        <th>Type of Work</th>
                        <th>Hobbies</th>
                        <th>Description</th>
                        <th>Favorite Color</th>
                    </tr>

                </thead>

                <tbody>

                </tbody>
            </table>

        );

    }
    componentDidMount() {
        this.showData();
    }

    showData() {
        let table = document.getElementById('editableTable');
        let x = table.rows.length;
        while (--x) {
            table.deleteRow(x);
        }
        let i = 0;
        for (i = 0; i < persons.length; i++) {
            let row = table.insertRow();
            let firstNameCell = row.insertCell(0);
            let lastNameCell = row.insertCell(1);
            let birthdayCell = row.insertCell(2);
            let salaryCell = row.insertCell(3);
            let choclatesCell = row.insertCell(4);
            let genderCell = row.insertCell(5);
            let workTypeCell = row.insertCell(6);
            let hobbiesCell = row.insertCell(7);
            let descriptionCell = row.insertCell(8);
            let colorCell = row.insertCell(9);


            firstNameCell.innerHTML = persons[i].firstName;
            lastNameCell.innerHTML = persons[i].lastName;
            birthdayCell.innerHTML = persons[i].birthday;
            salaryCell.innerHTML = persons[i].salary;
            choclatesCell.innerHTML = persons[i].Choclates;
            genderCell.innerHTML = persons[i].Gender;
            workTypeCell.innerHTML = persons[i].workType;
            hobbiesCell.innerHTML = persons[i].Hobbies;
            descriptionCell.innerHTML = persons[i].Description;
            colorCell.innerHTML = persons[i].favoriteColor;
            colorCell.style.backgroundColor = persons[i].favoriteColor;


        }
    }

}


export default Table;

表单组件

import React from 'react';

let persons = [];


if (JSON.parse(localStorage.getItem("personsForms")) !== null)
    persons = JSON.parse(localStorage.getItem("personsForms"));

.
.
.

handleSubmit = e => {
        e.preventDefault();

        let validation = this.validate();
        if (validation === true) {
            this.saveForm(this.state);
        }
        else {
            this.displayError(validation);
        }
    }

    validate() {
        const myForm = this.state;
        const errorsObj = [];
        if (myForm.firstName === "") {
            errorsObj.push('firstName');
        }
        if (myForm.lastName === "") {
            errorsObj.push('lastName');
        }
        if (myForm.birthday === "") {
            errorsObj.push('birthday');
        }
        if (myForm.salary === 0) {
            errorsObj.push('salary');
        }
        if (myForm.Choclates.length !== 3) {
            errorsObj.push('Choclates');
        }
        if (myForm.workType === "" || myForm.workType === null) {
            errorsObj.push('workType');
        }
        if (myForm.Hobbies.length < 2 || myForm.Hobbies.length > 4) {
            errorsObj.push('Hobbies');
        }
        if (myForm.Description === "") {
            errorsObj.push('Description');
        }
        if (errorsObj.length === 0) {
            return true;
        }
        else { return errorsObj; };
    }

    saveForm(myForm) {
        persons.push(myForm);
        localStorage.setItem("personsForms", JSON.stringify(persons)); 
    }

1 个答案:

答案 0 :(得分:1)

看看docs

当存储空间更改时,您需要添加window.addEventListener('storage', functionYouWantToCall)才能调用showData

我不知道要在哪里添加代码,因为您的代码有点乱,但是您需要添加

componentDidMount(){
    window.addEventListener('storage', this.showData)
}

componentWillUnmount(){
    window.removeEventListener('storage', this.showData)
}

编辑:

如评论中所述

  

...但是我想处理数组中的更改而不是localStorage中的更改。有什么想法吗?

您无法处理数组中的更改(我想它是变量persons),因为它在组件外部,并且永远不会更改。该值将设置一次,并且如果localStorage的值更改,persons不会更改。

这就是为什么您需要addEventListener的原因。

您应该做的是将persons存储在组件状态

state = { persons = [] }

componentDidMount中获取值并添加addEventListener

componentDidMount() {
    if (JSON.parse(localStorage.getItem("personsForms")) !== null){
        let persons = JSON.parse(localStorage.getItem("personsForms"));
        this.setState({ persons })
    } 

    window.addEventListener('storage', this.handlePersonsChange)
}

componentWillUnmount(){
    window.removeEventListener('storage', this.handlePersonsChange)
}

handlePersonsChange = () => {
    if (JSON.parse(localStorage.getItem("personsForms")) !== null){
        let persons = JSON.parse(localStorage.getItem("personsForms"));
        if(JSON.stringify(persons) === JSON.stringify(this.persons)){
            this.setState({ persons })
            this.showData()
        }
    } 
}

这样,您将localStorage的数组保留在组件的state中,并且localStorage检查personsForms是否已更改,然后调用showData

*您应该注意到JSON.stringify(persons) === JSON.stringify(this.persons)不好,但是如果您总是需要比较数组,可以对此进行一些搜索。

*还要注意,您有不需要的重复代码。

您可以简单地

if (JSON.parse(localStorage.getItem("personsForms")) !== null){
    let persons = JSON.parse(localStorage.getItem("personsForms"));

收件人

let localStoragePersons = JSON.parse(localStorage.getItem("personsForms"));
persons = localStoragePersons !== null ? localStoragePersons : []

这样,您就不会两次访问localStorage.getItem