呂學霖
呂學霖

Reputation: 53

good way to use different class css in react case by case?

I want use different color if the temperature is in adifferent zone.

Here is my code:

    const [weatherColor, setWeatherColor] = useState({
            temperature: '',
            humidity: ''
        })
    const colour = (temp, hum) => {
            let temperature = '';
            let humidity = '';
            if(temp < 11) temperature = 'bluegreen';
             else if(temp >= 11 && temp < 24) temperature = 'green';
             else if(temp >= 24 && temp < 36) temperature = 'orange';
             else if(temp > 36) temperature = 'purple';
             else temperature = 'gray';
            if(hum < 30) humidity = '30';
             else if(hum >= 30 && hum < 60) humidity = '60';
             else if(hum >= 60 && hum < 100) humidity = '100';
             else humidity = 'gray';
            setWeatherColor({temperature, humidity});
        }

Here's where I'm adding the CSS:

    <span className={`pt-8 text-temp-${weatherColor.temperature} text-[90px]`}>{observationalData.temperature}&#176;C</span>

Using console.log, I can see the value for ${weatherColor.temperature}, and it is what I expect: "text-temp-purple". However the color on my page does not change. What could be wrong?

Here is the whole code:

    import axios from 'axios';
    import { useEffect, useState } from 'react';
    import Icon from './Icon';
    
    const table = {
        day: {
            '晴天': { MappedIcon: Icon.SunDay },
            '多雲': { MappedIcon: Icon.CloudDay },
            '陰天': { MappedIcon: Icon.CloudyDay },
            '有雨': { MappedIcon: Icon.RainDay },
            '雷雨': { MappedIcon: Icon.RainLightningDay },
            '下雪': { MappedIcon: Icon.SnowDay },
        },
        night: {
            '晴天': { MappedIcon: Icon.SunNight },
            '多雲': { MappedIcon: Icon.CloudNight },
            '陰天': { MappedIcon: Icon.CloudyNight },
            '有雨': { MappedIcon: Icon.RainNight },
            '雷雨': { MappedIcon: Icon.RainLightningNight },
            '下雪': { MappedIcon: Icon.SnowNight },
        }
    }
    
    export default function Weather() {
        const [observationalData, setObservationalData] = useState({
            ctyName: '',
            townName: '',
            stationId: '',
            stationName: '',
            timestamp: 0,
            time: '',
            observationDate: '',
            observationTime: '',
            temperature: 0,
            day: '',
            title: '',
            humidity: 0
        });
    
        const [weatherColor, setWeatherColor] = useState({
            temperature: '',
            humidity: ''
        })
    
        const [WeatherIcon, setWeatherIcon] = useState();
    
        const colour = (temp, hum) => {
            let temperature = '';
            let humidity = '';
            if(temp < 11) temperature = 'bluegreen';
             else if(temp >= 11 && temp < 24) temperature = 'green';
             else if(temp >= 24 && temp < 36) temperature = 'orange';
             else if(temp > 36) temperature = 'purple';
             else temperature = 'gray';
            if(hum < 30) humidity = '30';
             else if(hum >= 30 && hum < 60) humidity = '60';
             else if(hum >= 60 && hum < 100) humidity = '100';
             else humidity = 'gray';
            setWeatherColor({temperature, humidity});
        }
    
        const getPosition = () => {
            if(!navigator.geolocation) {
                console.log('geolocation is not support');
            } else {
                const success = async (position) => {
                    const crd = position.coords;
                    const { latitude, longitude } = crd;
                    const data = await axios.get(`http://localhost:8000/api?latitude=${latitude}&longitude=${longitude}`);
                    setObservationalData(data.data);
                    const { MappedIcon } = table[observationalData.day][observationalData.title];
                    console.log(MappedIcon);
                    setWeatherIcon(MappedIcon);
                    colour(observationalData.temperature, observationalData.humidity);
                }
                const error = err => {
                    console.log('err', err.message);
                }
                navigator.geolocation.getCurrentPosition(success, error);
            }
        };
    
        useEffect(() => {
            const timer = setInterval(getPosition, 5000);
            console.log(new Date());
    
            return () => {
                clearInterval(timer);
            };
        });
        
        useEffect(() => {
            getPosition();
        }, []);
    
        return (
            <div className="flex">
                <div>{WeatherIcon ? <WeatherIcon /> : ''}</div>
                <div className="flex flex-wrap justify-center w-[664px]">
                    <span className={`pr-2 w-[50px] text-temp-${weatherColor.temperature} text-[40px]`}>溫度</span>
                    <span className={`pt-8 text-temp-${weatherColor.temperature} text-[90px]`}>{observationalData.temperature}&#176;C</span>
                    {console.log(`text-temp-${weatherColor.temperature}`)}
                    <span className="px-8">|</span>
                    <span className={`pr-2 text-rh-${weatherColor.humidity} w-[50px] text-[40px]`}>濕度</span>
                    <span className={`pt-8 text-rh-${weatherColor.humidity} text-[90px]`}>{observationalData.humidity}%</span>
                    <span className="text-[50px]">{observationalData.ctyName},{observationalData.townName}</span>
                </div>
            </div>
        )
    };

Upvotes: 2

Views: 94

Answers (1)

Ed Lucas
Ed Lucas

Reputation: 7305

The CSS file generated by Tailwind will only include classes that it recognizes when it scans your code, which means that dynamically generated classes (e.g. text-temp-${weatherColor.temperature}) will not be included unless each color utility-class (e.g. text-temp-purple) appears elsewhere in your code as a complete string.

You might solve this by setting the full utility class as your color:

if(temp < 11) temperature = 'text-temp-bluegreen';

...

<span className={`pt-8 ${weatherColor.temperature} text-[90px]`}>

Or saving the color value and using a style attribute:

if(temp < 11) temperature = '00DDDD';

...

<span style={{color: `#${weatherColor.temperature}`}} className={`pt-8x text-[90px]`}>

Or looking up the color string in an object and using a style attribute:

if(temp < 11) temperature = 'bluegreen';

...

const colors = {
  'bluegreen': '#00DDDD',
  'green': '#008000',
}

<span style={{color: colors?[weatherColor.temperature] ?? ''`}} className={`pt-8x text-[90px]`}>

More information: https://tailwindcss.com/docs/content-configuration#dynamic-class-names

Upvotes: 1

Related Questions