#reactjs #ionic-react
#reactjs #ionic-react
Вопрос:
Я довольно новичок в React и TypeScript, и я столкнулся с этой проблемой:
В моем пользовательском интерфейсе я использую несколько декоративных графических элементов следующим образом:
import Kitten from './img/Kitten.png';
<img className="Image" src={Kitten} />
Теперь у меня есть переключатель темного режима. Когда он срабатывает, я хочу заменить все изображения их соответствующей версией в темном режиме. Я думал о чем-то подобном:
import Kitten from './img/Kitten.png';
import DarkKitten from './img/DarkKitten.png';
//gets called when dark mode is toggled on or off
const darkModeToggleFunc = () => {
document.querySelectorAll('.Image').forEach(element => {
if(element.src.includes("Dark")) {
element.src = element.src.replace("Dark", "");
} else{
element.src = "Dark" element.src;
}
});
}
<img className="Image" src={Kitten} />
Теперь, в React у меня есть две проблемы: атрибут .src неизвестен, потому element
что не обязательно является изображением, и вторая проблема: я не назначаю URI как src, а переменную из импорта. Так что на самом деле нет ни одной строки, которую я мог бы изменить… Если я правильно информирован, React использует Base64 для изображений, указанных таким образом.
Как я мог бы достичь своей цели в React?
Редактировать: App.tsx
//bunch of imports
const App: React.FC = () => {
return (
<IonApp>
<IonReactRouter>
<IonSplitPane contentId="main">
<Menu />
<IonRouterOutlet id="main">
<Route path="/page/:name" component={Page} exact />
<Redirect from="/" to="/page/Production" exact />
</IonRouterOutlet>
</IonSplitPane>
</IonReactRouter>
</IonApp>
);
};
export default App;
Комментарии:
1. Могу ли я спросить, почему это помечено
react-native
при работе с элементами html? В любом случае, даже если вы хотите сделать это в react-native, реализация должна быть довольно похожей, но в случае, если это так, пожалуйста, создайте для этого отдельный вопрос. На данный момент я удалил тег.
Ответ №1:
Перво-наперво, когда дело доходит до react, вы не идете напрямую и не меняете что-то на уровне документа, вы обновляете виртуальный DOM и позволяете react позаботиться обо всем остальном.
Ваш сценарий связан с изменением темы приложения, этот ответ касается использования контекста реакции для изменения темы и надлежащего использования изображений.
Сначала вы создаете контекст, который будет содержать значение темы
const AppContext = createContext({
theme: "light",
setTheme: (theme) => {}
});
Здесь мы будем использовать переменную состояния для простоты, вы можете использовать все, что вам больше нравится.
Вот app.js файл
export default function App() {
const [theme, setTheme] = React.useState("light");
const themeState = { theme, setTheme };
return (
<AppContext.Provider value={themeState}>
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<ImageViewer />
<DarkModeSwitch />
</div>
</AppContext.Provider>
);
}
Здесь мы устанавливаем значение темы в состояние и устанавливаем контекст для этого, setTheme можно использовать для обновления темы из любого компонента, который находится в дереве. в вашем случае darkmodeswitch, здесь мы переключаем значение
const DarkModeSwitch = () => {
const { theme, setTheme } = useContext(AppContext);
const darkModeToggle = () => {
setTheme(theme === "light" ? "dark" : "light");
};
return (
<div>
<input
type="checkbox"
checked={theme === "light"}
onChange={() => darkModeToggle()}
/>
</div>
);
};
Переходя к вашему основному требованию, изображениям, давайте использовать общие файлы для изображений с содержимым
export const Kitten ="image source 1";
export const KittenDark ="image source 2";
Вы просто устанавливаете изображение на основе темы, как показано ниже
import { Kitten, KittenDark } from "./images";
export default function ImageViewer() {
const { theme } = useContext(AppContext);
return (
<img
alt="kitten"
style={{ height: 50, width: 100 }}
src={theme === "light" ? Kitten : KittenDark}
/>
);
}
как вы можете видеть, все связано через контекст, и как только вы обновите контекст, вы увидите, что изображения меняются.
Вы можете увидеть рабочую версию здесь
https://codesandbox.io/s/react-theme-switch-3hvbg
Это не «ПРАВИЛЬНЫЙ» способ, это один из способов обработки требований, вы можете использовать такие вещи, как redux и т. Д
Комментарии:
1. Я не согласен с заключительной частью вашего ответа, в то время как redux имеет свою полезность в определенных случаях, это не один из них, и установка нового пакета для того, что может быть элегантно обработано контекстом react, совершенно не нужна. В любом случае вы получили от меня 1.
2. Ну, это правда, но если он уже использует redux, он может его использовать, я родом из мира react-native, и у меня был вариант сохранения состояния redux, поэтому что-то вроде темы было бы полезно, большое спасибо за поддержку 🙂
3. Прежде всего, большое вам спасибо за этот подробный ответ! Я очень ценю подобные объяснения, чтобы я мог учиться. Я в пути, поэтому позже я сопоставлю ваш код с моим проектом, и если все сработает, я, конечно, отмечу ваш ответ 🙂
4. Итак, я вернулся домой. Во-первых, я застрял с кодом, который вы предоставили для файла app.js / tsx. Я добавил свой в свой исходный пост, не могли бы вы указать, как интегрировать ваш фрагмент?
5. у вас может быть состояние в app.js нравится мой образец и есть Контекст. Поставщик для переноса других компонентов