从本地存储中删除后如何重新渲染React组件?

3
我有两个组件:Display和DisplayList。这两个组件一起工作以从本地存储中显示值。所有都能正常工作,但是当我激活handleDelete方法时,本地存储中的值被删除,但React并未重新呈现列表。
总结:我希望在激活handleDelete()方法后,React能够重新呈现我的displayValues。 Github 链接

Display.JSX

import {DisplayList} from './DisplayList';


class Display extends Component {
  constructor(props){
    let data = JSON.parse(localStorage.getItem('data'));
    super(props)
    this.state = {
      data: data,
  }

  // Methods
  this.displayValues = this.displayValues.bind(this);
  }

  displayValues(){
   return this.state.data.map((data1, index) =>
    <DisplayList
      key = {index}
      email = {data1.email}
      password = {data1.password}
       /> 
    )

  }
  render() {
    return (
      <ul className="list-group">
        {this.displayValues()}
      </ul>
    )

  }
}

DisplayList.JSX

import {Button} from 'react-bootstrap';


export class DisplayList extends Component {
    constructor(props){
        super(props)


        // Methods
        this.handleDelete = this.handleDelete.bind(this);
    }


    handleDelete(){
        const data = JSON.parse(localStorage.getItem('data'));
        for (let index = 0; index < data.length; index++) {
            if(this.props.email === data[index].email &&
                this.props.password === data[index].password){
                data.splice(data[index], 1);
            }
        }
        localStorage.setItem('data', JSON.stringify(data));
    }

  render() {
    return (
    <div className = "mt-4">
        <li className="list-group-item text-justify">
            Email: {this.props.email} 
            <br /> 
            Password: {this.props.password}
            <br /> 
            <Button variant = "info mr-4 mt-1">Edit</Button>
            <Button onClick = {this.handleDelete} variant = "danger mt-1">Delete</Button>
        </li>  
    </div>
    )
  }
}

在从localStorage中删除时,也要从Display的状态中删除该项。 - Agney
2个回答

1
你可以通过将一个回调函数作为prop从Display.JSX传递到DisplayList.JSX来实现这一点。然后在handleDelete中触发回调并设置其父组件的状态。以下是示例代码。

Display.jsx

import {DisplayList} from './DisplayList';


class Display extends Component {
  constructor(props){
    let data = JSON.parse(localStorage.getItem('data'));
    super(props)
    this.state = {
      data: data,
  }

  // Methods
  this.displayValues = this.displayValues.bind(this);
  }

  displayValues(){
   return this.state.data.map((data1, index) =>
    <DisplayList
      key = {index}
      email = {data1.email}
      password = {data1.password}
      updateList = {this.updateList}
       /> 
    )

  }
  // This is the method that will be called from the child component.
  updateList = (data) => {
    this.setState({
      data
    });
  }
  render() {
    return (
      <ul className="list-group">
        {this.displayValues()}
      </ul>
    )

  }
}

DisplayList.jsx

import {Button} from 'react-bootstrap';


export class DisplayList extends Component {
    constructor(props){
        super(props)


        // Methods
        this.handleDelete = this.handleDelete.bind(this);
    }


    handleDelete(){
        const data = JSON.parse(localStorage.getItem('data'));
        for (let index = 0; index < data.length; index++) {
            if(this.props.email === data[index].email &&
                this.props.password === data[index].password){
                data.splice(data[index], 1);
            }
        }
        localStorage.setItem('data', JSON.stringify(data));
        this.props.updateList(data);
    }

  render() {
    return (
    <div className = "mt-4">
        <li className="list-group-item text-justify">
            Email: {this.props.email} 
            <br /> 
            Password: {this.props.password}
            <br /> 
            <Button variant = "info mr-4 mt-1">Edit</Button>
            <Button onClick = {this.handleDelete} variant = "danger mt-1">Delete</Button>
        </li>  
    </div>
    )
  }
}

1

你可以像被接受的答案一样操作,也可以有其他方法来完成这个操作,例如下面的方式:

将你的handleDelete事件移动到Parent中,因为你的状态data就在那里。

 class Display extends Component {
    constructor(props){
      let data = JSON.parse(localStorage.getItem('data'));
      super(props)
      this.state = {
        data: data || [{email: 'j', password: "dsv" }],
    }
  }


    handleDelete(email, password){
        const data = JSON.parse(localStorage.getItem('data'));
        data = data ? data : this.state.data
        for (let index = 0; index < data.length; index++) {
            if(email === data[index].email &&
                password === data[index].password){
                data.splice(data[index], 1);
            }
        }
        localStorage.setItem('data', JSON.stringify(data));
        this.setState({data});
    }

  render() {
    console.log(this.state)
    debugger
    return (
      <ul className="list-group">
        {this.state.data.map((data1, index) =>
          <DisplayList
            key = {index}
            email = {data1.email}
            password = {data1.password}
            handleDelete = {() => this.handleDelete(data1.email,data1.password )}
            /> 
          )}
      </ul>
    )

  }
}

DisplayList 中。
    export default class DisplayList extends Component {
    constructor(props){
        super(props)
    }


  render() {
    return (
    <div className = "mt-4">
        <li className="list-group-item text-justify">
            Email: {this.props.email} 
            <br /> 
            Password: {this.props.password}
            <br /> 
            <Button variant = "info mr-4 mt-1">Edit</Button>
            <Button onClick = {this.props.handleDelete} variant = "danger mt-1">Delete</Button>
        </li>  
    </div>
    )
  }
}

工作演示


你的解决方案也可以。无法说哪个更好。 - Arnas Dičkus
@ArnasDičkus 如果您只想删除操作,可以将 handleDelete 函数保留在父组件中。否则,您可以参考 Harsha Venkatram 的回答。 - Jayavel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接