React项目中无法将币种数据保存到localStorage设置默认选中值求助
解决方案
核心问题根因
- Context初始化时未优先读取localStorage存储的币种,硬编码的默认值
uiu不属于有效币种列表 - 拿到GraphQL返回的币种列表后,没有自动校验当前选中币种的有效性,也没有默认赋值第一个币种的逻辑
- 下拉选择器未绑定
value属性,无法和Context的选中值同步显示选中状态
代码修改
1. 修改CurrencyContext.js
初始化state时优先读取localStorage存储的币种,避免硬编码无效值:
import { createContext, Component } from 'react'; export const CurrencyContext = createContext() class CurrencyContextProvider extends Component { // 初始化优先读localStorage,没有的话先留空后续自动赋值 state = { selectedCurrency: localStorage.getItem('currency') || '' } setCurrency = (c) => { this.setState({selectedCurrency: c}) } render() { return ( <CurrencyContext.Provider value={{...this.state, setCurrency: this.setCurrency}}> {this.props.children} </CurrencyContext.Provider> ) } } export default CurrencyContextProvider;
2. 修改CurrencySelector.js
请求到币种列表后自动处理默认值,同时给下拉框绑定value属性同步选中状态:
import React from 'react'; import { CurrencyContext } from './CurrencyContext'; export class CurrencySelector extends React.Component{ // 绑定Context,方便在生命周期函数里访问 static contextType = CurrencyContext; constructor(props) { super(props) this.state = { currencies: [] } } async componentDidMount(){ let currencies = (await this.getCurrencies()).data.currencies this.setState({ currencies }, () => { // 拿到币种列表后处理默认值 const savedCurrency = localStorage.getItem('currency') // 校验本地存储的币种是否在有效列表里 const isValidCurrency = savedCurrency && currencies.includes(savedCurrency) const targetCurrency = isValidCurrency ? savedCurrency : currencies[0] // 同步到Context和localStorage this.context.setCurrency(targetCurrency) localStorage.setItem('currency', targetCurrency) }) } async getCurrencies(){ return await fetchTheQuery( `query{ currencies }` ) } render() { const {setCurrency, selectedCurrency} = this.context return( <select name="currency-selector" value={selectedCurrency} onChange={event => { setCurrency(event.target.value) localStorage.setItem("currency", event.target.value) }} > {this.state.currencies.map( (currency, index) => { return ( <option key={index} value={currency}> {currency} </option> ) } )} </select> ) } }
内容的提问来源于stack exchange,提问作者asem shaat
相关产品推荐
相关产品推荐

