В метеорологическом проекте React.js я хочу переключить переключатель между градусами Цельсия и Фаренгейта. Из родительского файла я получаю значение в градусах Цельсия для «М» и Фаренгейта для «I» в соответствии с единицами измерения в погодных условиях. От Цельсия до Фаренгейта и наоборот. Ниже приведен код для справки

  1. App.js (Родительский файл)
class App extends React.Component  { 
  constructor(props) {
    super(props);

    this.state = {
      isLoading: true,
      lat: '',
      lon: '',
      city: '',
      country: '',
      humidity: '',
      wind: '',
      description: '',
      maxTemp: '',
      minTemp: '',
      precip: '',
      pressure: '',
      hourlyforecast: '',
      error: '',
      sunrise: '',
      sunset: '',
      temp: '',
      unit: {
        M: 'M',
        I: 'I'
      }
    }
  }

  componentDidMount = async () => {

    // Here the state of units which is to be used later in api
    // according to toggle switch
    const unitType = (this.state.unit === 'M') ? 'M' : 'I';
    console.log('UNIT', unitType)

      // Tracking the location and 
      // Setting the state of latitude and longitude values
      navigator.geolocation.getCurrentPosition(async (position) => {
        this.setState({
          lat:  position.coords.latitude.toFixed(3),
          lon: position.coords.longitude.toFixed(3)
        }, () => {
          var lat = `${this.state.lat}`;
          var lon = `${this.state.lon}`;

  fetch(`${CURRENT_API}lat=${lat}&lon=${lon}&units=${unitType}&key=${API_KEY3}`)
  .then(res => res.json()).then(responseJson => {
    try {
      console.log('DATA CURRENT', responseJson)
    this.setState({
    city: responseJson.data[0].city_name,
    country: responseJson.data[0].country_code,
    temp: responseJson.data[0].temp,
    wind: responseJson.data[0].wind_spd,
    humidity: responseJson.data[0].rh,
    pressure: responseJson.data[0].pres,
    description: responseJson.data[0].weather.description,
    isLoading: false, 
    }, () => {
      localStorage.setItem('weather', JSON.stringify(this.state))
    })
    } catch {
      toast.error('Error Code 429')
    }
    console.log('STATE', this.state)

  });

  // Forecast Weather - Daily
  fetch(`${FORECAST_API}lat=${lat}&lon=${lon}&units=${unitType}&days=6&key=${API_KEY3}`)
  .then(res => res.json()).then(responseJson => {
    try {
      console.log('DATA I GET', responseJson)
      this.setState({ 
      forecastdays: responseJson.data,
      precip: responseJson.data[0].pop,
      maxTemp: responseJson.data[0].app_max_temp,
      minTemp: responseJson.data[0].app_min_temp,
      sunrise: responseJson.data[0].sunrise_ts,
      sunset: responseJson.data[0].sunset_ts,
      isLoading: false 
      } , () => {
        localStorage.setItem('weather', JSON.stringify(this.state))
      })
    } catch {
      toast.error('Too many requests')
    }

    console.log('STATE I GET', this.state)

  });


// Forecast Weather - Hourly
fetch(`${HOURLY_API}lat=${lat}&lon=${lon}&units=${unitType}&key=${API_KEY3}&hours=10`)
  .then(res => res.json()).then(responseJson => {
    try {
      this.setState({
        hourlyforecast: responseJson.data,
        isLoading: false
      }, () => {
        localStorage.setItem('weather', JSON.stringify(this.state))
      })

    } catch {
      toast.error('Please wait some time')
    }

  });
        })
        // Data auto-refreshed every 2 seconds

      },
      (error) => {
        toast.error(`${error.message}`,{
          autoClose: 3000
        })
      // toast.error(`ERROR(${error.code}): ${error.message}` )
    },
      {
        enableHighAccuracy: true,
        timeout: 50000,
        maximumAge: 1000
      })   
}

render() {
    const {isLoading, forecastdays, hourlyforecast, precip} = this.state;

    return (
      <div className="container" style={{marginTop: '3.5em'}}>
        <div className="row">
          {isLoading ? <Spinner/>:  

          <React.Fragment>
          <div className="col-sm-8 image-container">
          {/* Weather Card */}
          <div className="background">
          <div className="container"> 
          <div id="card" className="weather" style={sectionStyle}></div>    
          <div id="card" className="weather2" style={{background: ''}}>

                  <div className="details">
                      {/* Weather Details */}
                       <div className="content" style={{width: '125px'}}>
                       </div>

                      {/* Forecast Cards */}

                      <div className="content" style={{width: '360px', marginTop: '-40px'}}>

                             <div style={{display: 'table', width: '300px'}}>
                        // Celcius to Fahrenheit Toggle Button
                                <CeltoFahr 
                                  style={{display: 'table-cell'}}
                                  unit={this.state.unit}
                                />
                              </div>   
                       </div>
                      {/* Forecast Cards Ends*/  }          
                  </div> 
              </div>
           </div>
          </div>
          </div>
          {/* Weather Card Ends */}
          </React.Fragment>    
        }
        </div>
      </div>
    );
  }
}

export default App
  1. CelToFahr.js (кнопка тумблера)
import React, { Component } from 'react'
import CountUp from 'react-countup';
import './CelToFahr.css';

class CeltoFahr extends Component {
    state = {
        celOn: true
    }

    switchCel = () => {
        this.setState({ celOn: !this.state.celOn });

       //Here below in console.log I get the 'M' and 'I' both units
       //but, I want to set the state of 'M' when celOn is true
       // and 'I' when its false
        console.log('STATE', this.props.unit)
      };

    render() {
        return (
            <React.Fragment>
                {/* Code for celcius to farenheit */}
            <div className="weather" style={{margin: '-7em 0em 0em 11em'}}>
                <div className="figures" >
                    <div className="figuresWrap2">
                            <div style={{margin: '5em 0 0em 6em'}} 
                                onClick={this.switchCel} className="CelSwitchWrap">
                                <div className={"CelSwitch" + (this.state.celOn ? "" : " transition")}>
                                    <h3>°C</h3>
                                    <h3>°F</h3>
                                </div>
                            </div>
                    </div>
                </div>
            </div>
                {/*End of Code for celcius to farenheit */}
            </React.Fragment>
        )
    }
}

export default CeltoFahr

Как вы можете видеть в комментариях в методе switchSel (). Как переключаться между M и I, основываясь на щелчке пользователя, и запускать его в родительском компоненте, т.е. в файле App.js, или есть какая-то другая логика? Любой новый метод или предложение высоко ценится ... Спасибо

0
Pranav 10 Ноя 2019 в 12:52

2 ответа

Лучший ответ

Думаю, вы ищете это : {this.state.celOn ? <h3>{this.props.unit.M} °C</h3> : <h3>{this.props.unit.I} °F</h3>}

В App.js используйте это

switchCel = () => {
    this.setState({ celOn: !this.state.celOn });
};


<CeltoFahr 
   style={{display: 'table-cell'}}
   unit={this.state.unit}
   toggleBtn={this.switchCel}
/>
1
Rakib Uddin 16 Ноя 2019 в 14:05

Добавить юнит в ваш штат

state = {
    celOn: true,
    unit: this.props.unit.I
};

Поменяй свой переключатель cel на этот, чтобы он работал

switchCel = () => {
    const { M, I } = this.props.unit;
    this.setState({ celOn: !this.state.celOn, unit: this.state.celOn ? M : I });
};

Затем вы можете загрузить его в DOM, используя <h3>{thi.state.unit}C</h3>

1
Mohammed Farid 10 Ноя 2019 в 10:11