How to change styles in useable component in ReactJS - reactjs

I have following code.
This is my reusable components which name is "Blocks"
import React from "react";
import styles from "./Blocks.module.scss";
import cx from "classnames";
const Blocks = ({ newStyle }) => {
return (
<div className={cx(styles.blocksBox, { newStyle })}>
<div>
Some Text !!!
</div>
</div>
);
};
export default Blocks;
And this is styles from my "Blocks" component
.blocksBox {
display: grid;
grid-template-columns: 49% 50%;
padding: 10px 30px;
margin:20px;
column-gap: 30px;
}
Also I have another component which name is "MainBox", and I want to use "Blocks" component in "MainBox" with different styles. Below you can seethe code and new styles.
import React from "react";
import Blocks from "../Blocks";
import styles from "./MainBox.module.scss";
import cx from "classnames";
function MainBox() {
return (
<div>
<div> Some Text in Main Box </div>
<Blocks newStyle={styles.someStyle} />
</div>
);
}
export default MainBox;
.someStyle {
font-size: 50px;
color: red;
margin:30px;
}
But something was going wrong and new styles dose not applied, there is no any errors, I just write some wrong syntax, please help me resolve this problem

You can try concatinating styles like this:
import React from "react";
import styles from "./Blocks.module.scss";
import cx from "classnames";
const Blocks = ({ newStyle }) => {
return (
<div style= {[styles.blocksBox, newStyle ]}>
<div>
Some Text !!!
</div>
</div>
);
};
export default Blocks;
Example:
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default function App() {
return (
<View style={styles.container}>
<Box />
<Box newStyle={{ backgroundColor: 'yellow' }} />
</View>
);
}
const Box = ({ newStyle }) => {
return <View style={[styles.box, newStyle]}></View>;
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
box: {
backgroundColor: 'red',
width: 200,
height: 200,
},
});
output:
Expo Snack

I just deleted curly braces and everything started work
import React from "react";
import styles from "./Blocks.module.scss";
import cx from "classnames";
const Blocks = ({ newStyle }) => {
return (
<div className={cx(styles.blocksBox, newStyle )}>
<div>
Some Text !!!
</div>
</div>
);
};
export default Blocks;

Related

Toggling button image in React

I'm trying to toggle an icon in a button in react but I've tried everything and nothing works. I can change the background/text color toggling onClick but I'm missing something to change the icon and I don't know what! Any help?
Here's my code:
App.js
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { useState } from "react";
import Layout from "./layout";
import ThemeContext, { themes } from "./theme-context";
import { faSun, faMoon } from '#fortawesome/free-solid-svg-icons'
function App() {
const sun = <FontAwesomeIcon icon={faSun} />
const moon = <FontAwesomeIcon icon={faMoon} />
const [theme, setTheme] = useState(themes.dark)
const toggleTheme = () => theme === themes.dark ? setTheme(themes.light) : setTheme(themes.dark)
return (
<ThemeContext.Provider value={theme}>
<button onClick={toggleTheme}>
{sun}
</button>
<Layout />
</ThemeContext.Provider>
);
}
export default App;
theme-context.js
import React from "react"
export const themes = {
dark: {
color: "white",
background: "black",
padding: "5px",
width: "200px",
textAlign: "center",
},
light: {
color: "black",
background: "white",
padding: "5px",
width: "200px",
textAlign: "center",
}
}
const ThemeContext = React.createContext(themes.dark)
export default ThemeContext;
layout.jsx
import React, { useContext } from "react";
import ThemeContext from "./theme-context";
const Layout = () =>{
const theme = useContext(ThemeContext)
return (
<div style={theme} >
<p>This is your content</p>
</div>
)
}
export default Layout;
I have tried {themes.dark? : {sun} ? {moon}} but it didn't work.
The {themes.dark? : {sun} ? {moon}} was very close to correct (concept-wise, the syntax is not correct though). What you needed to do instead is { theme === themes.dark ? sun : moon } With your original snippet, you were just checking to see if themes.dark was truthy, which will always return true because it is an object. What you needed to do was check to see if the current theme was the same as themes.dark.
Hope this helps.

How to change button background color when I click the button in React using Hooks

I am working on a React project, In my project I have two buttons, for First button I assigned a state for second button I written a function and I assigned a state as well. but my onClick function is not working. please help me to resolve this isssue.
This is App.js
import React, { useState } from "react";
import { Button } from "antd"
import 'antd/dist/antd.css';
import "./App.css";
const App = () => {
const [buttonOne, setButtonOne] = useState("red")
const [buttonTwo, setButtonTwo] = useState("blue")
const buttonTwoBackgroundColor = () => {
setButtonTwo({
backgroundColor: "red",
border: "red"
})
}
return (
<div>
<Button style={{backgroundColor: buttonOne, border: buttonOne}} className="one" type="primary">First</Button>
<Button style={{backgroundColor: buttonTwo, border: buttonTwo}} onClick={buttonTwoBackgroundColor} className="two" type="primary">Second</Button>
</div>
)
}
export default App
This is App.css
.one {
margin-right: 5px;
margin-left: 250px;
margin-top: 50px;
}
.two, .three, .four, .five {
margin-right: 5px;
}
In the function buttonTwoBackgroundColor you set setButtonTwo to a object. it should be a string.
const buttonTwoBackgroundColor = () => {
setButtonTwo("red")
}
change
onClick={buttonTwoBackgroundColor}
to
onClick={setButtonTwo("red")}
you are using useState as string at initialization and assigning an object in function below, which is not proper way!
You are trying to set state to be an object when you have defined the defualt state as a string.
Update the default state to an object and then access properties like this:
import React, { useState } from "react";
import { Button } from "antd";
import "./styles.css";
export default function App() {
const [buttonOne, setButtonOne] = useState("red");
const [buttonTwo, setButtonTwo] = useState({backgroundColor: "blue", border: "blue"});
const buttonTwoBackgroundColor = () => {
setButtonTwo(prevState => ({
...prevState,
backgroundColor: 'blue',
border: 'red'
}));
};
return (
<div>
<Button
style={{ backgroundColor: buttonOne, border: buttonOne }}
className="one"
type="primary"
>
First
</Button>
<Button
style={{ backgroundColor: buttonTwo.backgroundColor, border: buttonTwo.border }}
onClick={buttonTwoBackgroundColor}
className="two"
type="primary"
>
Second
</Button>
</div>
);
}

How do I create stack navigation tabs for a separate .tsx file in react js

At the start of my application, there is two tabs at the bottom of the screen (these tabs came in the template I downloaded from Expo for react js). I made a new screen, called homepage, and I want to now replicate those same tabs at the bottom, but I can't figure out how. I tried using a stack navigator but it did not work.
I want it to look like this
Here is my code for homescreen
import * as React from 'react';
import { StyleSheet, Button, TextInput } from 'react-native';
import EditScreenInfo from '../components/EditScreenInfo';
import { Text, View } from '../components/Themed';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import FAQ_Screen from './FAQ_Screen';
import NewsScreen from './NewsScreen';
import { createStackNavigator } from '#react-navigation/stack';
import BottomTabNavigator from '../navigation/BottomTabNavigator';
import NotFoundScreen from './NotFoundScreen';
const Stack = createStackNavigator();
export default function HomeScreen() {
return (
<View style={styles.container}>
<Text> Home </Text>
<select>
<option> Station 1 </option>
<option> Staton 2 </option>
</select>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
title: {
fontSize: 20,
fontWeight: 'bold',
},
separator: {
marginVertical: 30,
height: 1,
width: '80%',
},
});
You should declare tabs inside Tab.Navigator.
These screens can be separate .tsx or js files. I did using js, to be able to show using Expo. However, ts/js doesn't change the behavior.
I did a working example:
https://snack.expo.io/#mayconjcm/tab-navigation-%7C-react-navigation
You can also see the code here:
Home:
import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import HomeTab from './Tab1';
import SettingsTab from './Tab2';
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeTab} />
<Tab.Screen name="Settings" component={SettingsTab} />
</Tab.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<MyTabs />
</NavigationContainer>
);
}
Tab1:
import * as React from 'react';
import { Text, View } from 'react-native';
const HomeTab = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
export default HomeTab;
Tab2:
import * as React from 'react';
import { Text, View } from 'react-native';
const SettingsTab = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
export default SettingsTab;

What is the proper way of using the styling defined inside createMuiTheme alongside with Material-UI's useStyles?

import React from 'react';
import Component from './components/Component';
import { createMuiTheme, makeStyles, ThemeProvider } from '#material-ui/core/styles';;
const theme = createMuiTheme({
container: {
width: '100%',
paddingRight: '15px',
paddingLeft: '15px',
marginRight: 'auto',
marginLeft: 'auto'
},
flexColumn: {
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}
});
function App() {
return (
<ThemeProvider theme={theme}>
<div className="App">
<Component />
</div>
</ThemeProvider>
);
}
export default App;
The theme provided above goes inside the component Component.
import React, { useState } from "react";
import { makeStyles } from '#material-ui/core/styles';
import { useTheme } from '#material-ui/core/styles';
import classNames from 'classnames';
const useStyles = makeStyles(() => ({
bar: {
flexGrow: 1,
padding: '.8rem .8rem',
lineHeight: '1.5em',
fontSize: '18px',
},
alert: {
color: 'white',
backgroundColor: 'red',
},
}));
export default function Component (props) {
const theme = useTheme();
const classes = useStyles();
const [focus, setFocus] = useState(false);
return (
<div>
<div style={theme.flexColumn} className={classNames(classes.alert, classes.bar)}>
<div>
</div>
</div>
</div>
);
}
Is this the proper way to use useTheme and className? The issue with this is that I can't use the styles defined with createMuiTheme and fetched through the ThemeProvider inside the className attribute, which means sometimes the styling inside classNames and style may conflict with one another. I couldn't find an example where the styling provided inside createMuiTheme is used with className.
If you want to reuse classes in MUI, you should create an external style file, then import this file into the components that you want to use this style. Try this:
In sharedStyles:
export const layout = {
header: {
fontSize: "1.5em",
color: "blue"
},
footer: {
fontSize: "0.8em"
}
};
const sharedStyles = theme => ({
grow: {
flexGrow: 1
},
defaultPadding: {
padding: theme.spacing.unit * 3 + "px"
},
"layout.header": layout.header
});
export default sharedStyles;
In a component:
import React from "react";
import { withStyles } from "#material-ui/core/styles";
import Paper from "#material-ui/core/Paper";
import sharedStyles, { layout } from "./sharedStyles";
import Typography from "#material-ui/core/Typography";
function Dashboard(props) {
const { classes } = props;
return (
<Paper className={classes.defaultPadding}>
<Typography variant="body1" gutterBottom>
Hello <span className={classes.someOtherStyle}>World</span>
</Typography>
<Typography
component="h2"
variant="h1"
gutterBottom
className={classes["layout.header"]}
>
Heading
</Typography>
<Typography
component="h2"
variant="h1"
gutterBottom
className={classes.header}
>
Heading 2
</Typography>
</Paper>
);
}
const styles = theme => ({
...sharedStyles(theme),
header: layout.header,
someOtherStyle: {
color: "red"
}
});
export default withStyles(styles)(Dashboard);

Using material-ui's APIs, how do I set a background image in the body?

I want to set a background image in the body of my web app using material-ui-next's CSS-in-JS, withStyles, or themes? I would like to avoid using an external CSS file if possible.
You can inject css into the outer scope with "#global" using withStyles from "#material-ui/core/styles"
import React, { Fragment } from "react";
import CssBaseline from "#material-ui/core/CssBaseline";
import { withStyles } from "#material-ui/core/styles";
import Main from "./Main";
const styles = theme => ({
"#global": {
body: {
backgroundImage: "url('/media/landing.jpg')",
backgroundRepeat: "no-repeat",
backgroundPosition: "center center",
backgroundSize: "cover",
backgroundAttachment: "fixed",
height: "100%"
},
html: {
height: "100%"
},
"#componentWithId": {
height: "100%"
}
}
});
const App = () => {
return (
<Fragment>
<CssBaseline />
<Main />
</Fragment>
);
};
export default withStyles(styles)(App);

Resources