本地存储值更改后页面未更新,请执行REACT

时间:2019-03-06 09:14:28

标签: javascript reactjs

我有一个this.state.language,可以通过app.js中的localstorage进行操作。但是,我将此值作为prop传递给我的路由,无论该值是多少,我都有一条if语句从json文件加载数据。例如,如果值为'en',则从data.en加载数据;如果值为'es',则从data.es加载数据。所以我的问题是,每当切换localstorage值时,它将在json中加载正确的数据,但是如果我切换页面,则不会。我尝试使用this.propsthis.state而不使用状态,而是直接通过localstorage.getItem()获取状态。

App.js

constructor(){
    super();
    this.state = {
      sideNav: '',
      language: localStorage.getItem('language')
    }
    this.langEn = this.langEn.bind(this);
    this.langEs = this.langEs.bind(this);
  }

  langEn() {
    this.setState({language: 'en'}, () => localStorage.setItem('language', JSON.stringify(this.state.language)));
    console.log(this.state);
  }

  langEs() {
    this.setState({language: 'es'}, () => localStorage.setItem('language', JSON.stringify(this.state.language)));
    console.log(this.state);
  }

另一页上的代码,用于根据本地存储值是什么来加载json数据

class NewFormDetails extends Component {
    constructor(props) {
        super(props);

        this.state = {
            language: this.props.language,
            siteName: '',
            counties: '',
            siteAddress: '',
            siteEmail: '',
            siteNumber: '',
            siteCat: '',
            openTimes: '',
            fees: '',
            access: '',
            gps: '',
            w3w: '',
            txtHeader: '',
            txtContent: ''
        };

    }

    validateForm() {
        if (this.state.siteName != '' &&
            this.state.siteAddress != '' &&
            this.state.siteEmail != '' &&
            this.state.siteNumber != '' &&
            this.state.openTimes != '' && 
            this.state.fees != '' && 
            this.state.access != '' && 
            this.state.gps != '' && 
            this.state.w3w != '' && 
            this.state.txtHeader != '' && 
            this.state.txtContent != '') {
                return true;
            } else {
                return false;
            }
    }

    handleChange = e => {
        this.setState({ ...this.state, [e.target.name]: e.target.value });
        console.log(this.state);
    }

    handleSubmit = event => {
        event.preventDefault();
        console.log(this.state);
        this.props.history.push('/newSite/tours');
    }

    render() {

        let jsonLang;

        if (this.props.language == 'en') {
            jsonLang = data.en;
        } else if (this.props.language == 'es') {
            jsonLang = data.es;
        } else {
            jsonLang = data.en;
        }

        this.placeholders = jsonLang.placeholders;
        this.counties = jsonLang.counties;
        this.categories = jsonLang.categories;

1 个答案:

答案 0 :(得分:0)

您存储的语言值不正确。您正在像这样获取

this.state = {
  sideNav: '',
  language: localStorage.getItem('language')
}

...但是然后像这样存储它:

localStorage.setItem('language', JSON.stringify(this.state.language));

这意味着您最终将"en"(或"es")存储在本地存储(包括引号)中,而不是enes。稍后刷新页面时,该页面与您的任何data项目都不匹配,因此默认为data.en

由于language是一个字符串,因此无需使用JSON。只是:

localStorage.setItem('language', this.state.language);

还有另一个问题:您不允许页面加载且language中没有localStorage值。在您的情况下,可以使用||惯用语,因为如果项目不存在,localStorage.getItem返回null

this.state = {
  sideNav: '',
  language: localStorage.getItem('language') || 'en'
};

(我还在那里添加了缺少的;。)

您可能想更进一步并进行验证:

const defLanguage = 'en';
let language = localStorage.getItem('language') || defLanguage;
if (!data[language]) {
    language = defLanguage;
}
this.state = {
  sideNav: '',
  language
};

您甚至可以在与defLanguage相同的级别(及其旁边)定义data,因此您可以在应用默认设置的任何地方使用它。


正如我在对上一个问题的评论中提到的那样,在组件中使用this.props.language时,您可以替换

if (this.props.language == 'en') {
    jsonLang = data.en;
} else if (this.props.language == 'es') {
    jsonLang = data.es;
} else {
    jsonLang = data.en;
}

只需:

jsonLang = data[this.props.language] || data.en;

或者如果您做defLanguage事情:

jsonLang = data[this.props.language] || data[defLanguage];