Я создаю приложение погоды в React, и пока все хорошо. Проблема в том, что теперь я хочу иметь «светлый режим» и «темный режим», которые должны быть классами CSS, которые меняются в зависимости от времени восхода/захода солнца, полученного API. Когда я делал это в ванильном JS, я использовал функцию, которая преобразовывала метки времени в часы и сравнивала текущий час с восходом/закатом, а затем решала, какой класс представить, вот так
function getMode(response) {
let today = response.data.dt;
let timezone = response.data.timezone;
let difference = today + timezone - 3600;
let hours = timeConverter(difference);
let mode = document.getElementById("app");
let sunrise = response.data.sys.sunrise;
let difference2 = sunrise + timezone - 3600;
let currentSunrise = timeConverter(difference2);
let sunset = response.data.sys.sunset;
let difference3 = sunset + timezone - 3600;
let currentSunset = timeConverter(difference3) - 1;
if (hours > currentSunset) {
mode.classList.add("darkmode").remove("lightmode");
}
else if (hours < currentSunrise) {
mode.classList.add("darkmode").remove("lightmode");
} else {
mode.classList.remove("darkmode").add("lightmode");
}
}
axios.get(apiUrl).then(getMode)
<body>
<div id = "app" class = "lightmode">
Тогда CSS выглядел так
.lightmode h1 {
font-family: "Josefin Sans", sans-serif;
text-align: right;
color: #06384d;
font-size: 32px;
font-weight: 700;
}
.lightmode {
font-family: "Josefin Sans", sans-serif;
background-image: linear-gradient(120deg, #a1c4fd 0%, #c2e9fb 100%);
border-style: solid;
border-radius: 30px;
border-color: #096386;
}
#app {
margin: 10px 400px;
padding: 10px 10px;
}
(...)
.darkmode h1 {
font-family: "Josefin Sans", sans-serif;
text-align: right;
color: #fff;
font-size: 32px;
font-weight: 700;
}
.darkmode {
font-family: "Josefin Sans", sans-serif;
background-image: linear-gradient(to top, #30cfd0 0%, #330867 100%);
border-style: solid;
border-radius: 30px;
border-color: #096386;
}
И это работало нормально. Теперь в React (новичок здесь) я не знаю, как подойти к проблеме. Я читал о динамическом изменении классов CSS в React с состоянием, но не могу понять, как включить это в ответ API. Какие-либо предложения?






Ключевой частью динамически изменяющихся классов CSS в React будет:
<div className = {`App ${this.state.displayMode}`}>
Имя класса контейнера будет обновляться каждый раз, когда изменяется состояние displayMode и в этом примере добавляется к классу App, что приводит к App darkmode и отображается как таковое.
<div class = "App darkmode">
Пример кода/вариант использования:
class App extends Component {
state = {
displayMode: "lightmode"
};
getMode = response => {
let _displayMode;
// Logic for determining the mode
return _displayMode;
}
componentDidMount() {
// Make API call here and run your logic to determine the mode
axios.get(apiUrl).then(getMode).then(displayMode => {
// As a callback to your function, set the state for displayMode
this.setState({
displayMode: displayMode
})
});
}
render() {
return (
<div className = {`App ${this.state.displayMode}`}>
</div>
);
}
}
Вы можете сохранить className в состоянии и изменить его в своей функции.
class Demo extends Component {
constructor(props) {
super(props);
this.state = {
stClass: "lightmode"
}
}
state = {
stClass: "lightmode"
}
componentDidMount = () => {
[call your function here and change the state of stClass]
}
render() {
return (
<div className = {`${this.state.stClass}`}>
[your code here]
</div>
)
}
}
Рад был помочь :)
Я использовал вариант вашего решения, чтобы лучше соответствовать моему коду (у меня уже есть
componentDidMount, что означает, что я не могу вызывать его по аксиомам, он не будет знать, какой из них вызывать), и он работает нормально! Благодарю вас!