【问题标题】:LocalStorage not working properly ReactJSLocalStorage 无法正常工作 ReactJS
【发布时间】:2019-08-13 16:43:29
【问题描述】:

我在表格中设置了一个数组,因此当我单击一个图标时,会在该特定行中重新呈现一个不同的图标。现在我有本地存储设置,因此当我刷新页面时,状态会保持不变。我遇到的问题是,如果我点击 4 个图标,显然会重新渲染 4 个不同的图标,但是当我刷新页面时,我点击的 last 会恢复到原来的状态,所以现在我只有 3 个重新渲染的图标。我该如何解决这个问题?

import React from 'react';
import StarBorder from '@material-ui/icons/StarBorder';
import Star from '@material-ui/icons/Star';
import axios from 'axios';

class Test extends React.Component {
    constructor(props) {
        super(props);

        var newData = [];

        if (localStorage.getItem('new')) {
            newData =  JSON.parse(localStorage.getItem('new'));
        }

        this.state = {
          data: newData,
        }
    }

    componentDidMount() {

        if (!localStorage.getItem('new')) {
            axios.get('https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=100&page=1&sparkline=true')
            .then(res => {
                const data = res.data;
                this.setState({  data: data.map(x => ({...x, starIcon: true})) })
            })
        }
    }

    handleClick = (i) => {

        this.setState(prevState => ({
          data: prevState.data.map((x, key) => (key === i ? {...x, starIcon: !x. starIcon} : x))
        }));

          localStorage.setItem('new', JSON.stringify(this.state.data));
      }

    render() {
        return (
        <div>
            <table border="1">
                <thead>
                    <tr>
                    <td>Icon</td>
                    <td>Name</td>
                    <td>Price</td>
                    </tr>
                </thead>
                <tbody>
                {this.state.data.map((n, i) => {
                    return (
                        <tr>
                        <td> <span onClick={() => this.handleClick(i)}> {n.starIcon ? <StarBorder/> : <Star /> } </span> </td>
                        <td>{n.name}</td>
                        <td>{n.current_price}</td>
                        </tr>
                    );
                    })}
                </tbody>
            </table>
        </div>
        );
    }
}

export default Test;

【问题讨论】:

    标签: reactjs local-storage


    【解决方案1】:

    setState 是异步的,因此当您将项目设置为本地存储时,您可能仍会捕获以前的状态。要修复它,请使用setState 的回调函数来确保在设置项目时更新状态:

      handleClick = (i) => {
       this.setState(prevState => ({
         data: prevState.data.map((x, key) => (key === i ? {
           ...x,
           starIcon: !x.starIcon
         } : x))
       }), () => {
         localStorage.setItem('new', JSON.stringify(this.state.data));
       });
     }
    
    

    【讨论】:

      【解决方案2】:

      你将不得不改变handleClick函数,因为在setState设置它的状态之前,本地存储的setitem方法被调用了。 所以你必须使用 setState 方法的回调函数

      Why is setState in reactjs Async instead of Sync?

      handleClick = (i) => {
         this.setState(prevState => ({
           data: prevState.data.map((x, key) => (key === i ? {
             ...x,
             starIcon: !x.starIcon
           } : x))
         }), () => {
           localStorage.setItem('new', JSON.stringify(this.state.data));
         });
       }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多