Estoy construyendo un comercio electrónico con React, en el cual hay un menú desplegable que tiene diferentes monedas. Las monedas provienen de un punto final de GraphQL que tiene toda la información. Cuando el usuario elige una moneda, cambia los precios listados. Eso es implementado por un contexto y consumo ese contexto en el componente selector de moneda. Todo esto funciona bien, sin embargo, cuando inicio la web desde el principio, no aparece nada ya que no hay una moneda guardada de forma predeterminada. Estoy tratando de guardar la primera moneda en el menú desplegable en el almacenamiento local y configurarlo en el contexto, pero nada de esto funcionó para mí. Por favor, hágamelo saber lo que me recomienda para hacer eso?
Adjuntaré mi código a continuación para el componente selector de moneda y el contexto de la moneda.
MonedaContexto.js
export const CurrencyContext = createContext() class CurrencyContextProvider extends Component { state = {selectedCurrency: 'uiu'} setCurrency = (c)=>{ this.setState({selectedCurrency: c}) } render() { return ( <CurrencyContext.Provider value={{...this.state, setCurrency: this.setCurrency}}> {this.props.children} </CurrencyContext.Provider> ) } } export default CurrencyContextProvider;MonedaSelector.js
export class CurrencySelector extends React.Component{ constructor(props) { super(props) this.state = { currencies: [] } } async componentDidMount(){ let currencies = (await this.getCurrencies()).data.currencies this.setState({ currencies:currencies } ) } async getCurrencies(){ return await fetchTheQuery( `query{ currencies }` ) } render() { return ( <CurrencyContext.Consumer> {(currencyContext) => { const {setCurrency} =currencyContext return( <select name="currency-selector" onChange={event => { setCurrency(event.target.value) localStorage.setItem("currency", event.target.value) }}> {this.state.currencies.map( (currency, index) => { return ( <option value={currency}> {currency} </option> ) } )} </select> ) }} </CurrencyContext.Consumer> ) } }Si entendí su problema correctamente, debe cargar el valor predeterminado en el cuadro de selección antes de que la API devuelva los datos. También desea mantener el valor anterior elegido por el usuario como el valor seleccionado cuando la API de GraphQL recibe la respuesta. Esto es lo que puede hacer: en contextProvider , cargue el valor predeterminado de localStorage de la siguiente manera:
function getDefaultValue() { const currency = localStorage.getItem('currency'); return currency ? currency : 'USD'; } const defaultVal = getDefaultValue(); //Insert the default value here. export const CurrencyContext = createContext(); class CurrencyContextProvider extends Component { constructor(props) { super(props); this.state = { selectedCurrency: defaultVal }; // initial value in state this.setCurrency = this.setCurrency.bind(this); } ... rest of the code Ahora, el consumidor recibirá la moneda selectedCurrency con el valor predeterminado del localStorage .
Ahora en el consumidor, debe verificar y alternar las opciones en blanco y negro:
{currencies.length ? currencies.map((currency, index) => { return <option value={currency}>{currency}</option>; }) : // render the default currency from context when currency is not loaded [selectedCurrency].map((currency, index) => { return <option value={currency}>{currency}</option>; })} También debe establecer la propiedad de value en select con selectedCurrency .
Aquí está el ejemplo de trabajo: Stackblitz Demo
PD: debería considerar mover todo el código a componentes funcionales y utilizar useContext .
¿Es posible que la función onChange no se esté ejecutando actualmente?
Tal vez pueda aislar la función que pasa a onChange a una función de clase llamada handleChange .