why i'm getting an undefined in here? - reactjs

I'm building this code in when a user clicks the image, it should assign the newstyle to the style state. But whenever I click in a position of the image, it pops up an newStyle is undefined error even when I've set the variable newStyle inside the imageClick function.
import React, {useState} from 'react'
import mainImage from '../img/marioBrosMain.jpg'
import '../main.css'
import Box from '../pages/box.js'
function Main() {
const [style, setStyle] = useState();
const imageClick = (x, y) => {
const newStyle = `position: absolute,
z-index: 2,
border-radius: 2px solid red,
border: 2px solid red,
height: 50px,
padding-left: 50px,
margin-left: 1450px,
left:${x}px,
top:${y}px`
return newStyle
}
return (
<div id="frame">
<div id="mainImage" style = {style}></div>
<img src={mainImage} className="marioBros____image" onClick={e => {
imageClick(e.screenX, e.screenY);
setStyle(newStyle);
}}/>
</div>
)
}
export default Main

It looks like newStyle is not in scope in the code you have posted. Maybe something like this would work:
<img
src={mainImage}
className="marioBros____image"
onClick={e => setStyle(imageClick(e.screenX, e.screenY)) }
/>
This way you're directly setting the style with the return value from imageClick.

I think this is the optimal code.
import React, { useState } from "react"
import mainImage from "../img/marioBrosMain.jpg"
import "../main.css"
import Box from "../pages/box.js"
export default function Main() {
const [style, setStyle] = useState()
const imageClick = (x, y) => ({
position: "absolute",
zIndex: 2,
borderRadius: 2,
borderColor: "red",
borderStyle: "solid",
height: 50,
paddingLeft: 50,
marginLeft: 1450,
left: x,
top: y
})
return (
<div id="frame">
<div id="mainImage" style={{}}></div>
<img src={mainImage} className="marioBros____image" onClick={e => setStyle(imageClick(e.screenX, e.screenY))} />
</div>
)

Related

In fabric.js ( react.js) how can i add canvas objects on onClick?

It works if I adds the code into useEffect but on onClick no object is showing.
I want to show canvas objects on onClick.
import { useEffect, useState } from 'react';
import { fabric } from 'fabric';
const Canvasbody = () => {
const canvas = new fabric.Canvas('canvas-main');
function RectB(canvi) {
const rect = new fabric.Rect({
height: 280,
width: 200,
fill: 'yellow',
});
canvi.add(rect);
}
return (
<>
<canvas
style={{ border: 'solid 1px #555' }}
id="canvas-main"
width="600px"
height="600px"
/>
<button onClick={() => RectB(canvas)}>Click me</button>
</>
);
};
Try using canvi.renderAll() after adding rect to canvas in your function.

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 can you detect if the position clicked is correct?

I'm trying to build a find waldo and to do that, I need to assign a position in where the character is located. To do this, I've thought of assigning the position of the X and Y with e.pageX and e.PageY, the problem is that the image is very big so yo need to scroll to see all the image.
So the position changes each time I scroll. I've been thinking a way of checking if the character clicked is correct but I can't seem to find a way to do that... If anyone could help me please I woild really appreciate it.
Here is the code:
import React, {useState} from 'react'
import mainImage from '../img/marioBrosMain.jpg'
import '../main.css'
import Box from '../pages/box.js'
function Main() {
const [style, setStyle] = useState();
const [hidden, setHidden] = useState(true)
let Characters;
const imageClick = (x, y) => {
const newStyle = {
position: "absolute",
zIndex: 2,
borderRadius: "2px solid red",
border: "4px solid red",
height: "50px",
paddingLeft: "10px",
left: `${x}px`,
top: `${y}px`
}
setHidden(false)
return newStyle
}
if (!hidden) {
Characters = (
<>
<div className="hello">
<div>
<button>Star</button>
</div>
<div>
<button>Mario</button>
</div>
<div>
<button>Yoshi</button>
</div>
</div>
</>
);
}
return (
<div id="frame">
<div id="mainImage" style = {style}>
{Characters}
</div>
<img src={mainImage} className="marioBros____image" onClick={(e) => {setStyle(imageClick(e.pageX, e.pageY)); console.log(e.pageX)}} />
</div>
)
}
export default Main

Setting responsive handlers in React then using them in scss

I have a custom Hook that detects whether the app is the mobile or desktop version. Serving up 2 versions of components works but I am at a loss on how to pass the variable to a scss file.
The code sandbox demo is here.
In my app.js I have a couple of classes that are modified based on #media (max-width: 768px) within the scss file. This would be fine if I only had 1 style but with multiple styles, I would like to find a way to set in React which style to use.
How do I use {windowSize} to pass a JS variable to a .scss file? If I used styled-component what would it look like?
import "./app.scss";
import useWindowSize from "./useWindowSize";
export default function App() {
const windowSize = useWindowSize();
return (
<div className="App">
<h1>Making the app responsive</h1>
<h2 className="TestTitle">{windowSize}</h2>
<p className="BoxWidth">Hello world</p>
</div>
);
}
Styling looks like this:
$width: 768px;
$Colour1: rgb(0, 255, 213);
.BoxWidth {
background-color: green;
#media (max-width: $width) {
background-color: lightblue;
}
}
This is how you can do it with styled-components:
const Box = styled.div` // or 'p' depending on which element you want to use
background-color: green;
// Note that you are using a 'width' prop that needs to be passed in
#media (max-width: ${({ width }) => width}) {
background-color: lightblue;
}
`;
export default function App() {
const windowSize = useWindowSize();
return (
<div className="App">
...
// You pass the window size in as the width prop
<Box width={windowSize}>Hello world</Box>
</div>
);
}
See your modified codesandbox
EDIT
We clarified the question in chat. To which this is the solution:
const commonStyles = { background: "pink", height: 100, margin: "0 auto" };
const SmallComponent = () => <div style={{ ...commonStyles, width: "100%" }} />;
const LargeComponent = () => (
<div style={{ ...commonStyles, width: "500px" }} />
);
const Box = styled.div`
color: white;
background-color: ${({ isMobile }) => (isMobile ? "green" : "lightblue")};
`;
export default function App() {
const windowSize = useWindowSize();
const isMobile = windowSize === "useMobileVersion";
return (
<div className="App">
<h1>Making the app responsive</h1>
<h2>{windowSize}</h2>
<Box isMobile={isMobile}>Hello world</Box>
{isMobile ? <SmallComponent /> : <LargeComponent />}
</div>
);
}
The original codesandbox link has been updated with this latest answer.
You can just use if else.
For example:
export default function App() {
const windowSize = useWindowSize();
const csTestTiele = windowSize <= 768 ? "TestTitleSmall" : "TestTitleNormal";
const csBoxWidth = windowSize <= 768 ? "BoxWidthSmall" : "BoxWidthNormal";
return (
<div className="App">
<h1>Making the app responsive</h1>
<h2 className={csTestTiele}>{windowSize}</h2>
<p className={csBoxWidth}>Hello world</p>
</div>
);
}
or use classnames library:
import cs from 'classnames';
export default function App() {
const windowSize = useWindowSize();
const csTestTiele = cs({
TestTieleSmall: windowSize <= 768,
TestTieleNormal: windowSize > 768,
});
const csBoxWidth = cs({
BoxWidthSmall: windowSize <= 768,
BoxWidthNormal: windowSize > 768,
});
return (
<div className="App">
<h1>Making the app responsive</h1>
<h2 className={csTestTiele}>{windowSize}</h2>
<p className={csBoxWidth}>Hello world</p>
</div>
);
}

How to change grayscale using hooks in react?

I want to change on the image slider used with UI material when I drag on the slider, but it changes only grayscale but nothing happens on the slider, why?
I will try to do function but I don't have idea how to do? somebody have?
import React, { useState, useEffect } from 'react';
import logo from '../logo.svg';
import defaultImage from '../Image/sen.jpg';
import Typography from "#material-ui/core/Typography";
import Slider from "#material-ui/lab/Slider";
function ImageSlider ({ value, max, onChange, children }) {
return (
<>
<Typography id="label">
{children}
</Typography>
<Slider className="slider"
min={0}
max={max}
value={value}
aria-labelledby="label"
step={1}
onChange={onChange}
/>
</>
)
}
export default function Hooks () {
const [name, setName] = useState('Franek!');
const [contrast, setContrast] = useState('100%');
const [brightness, setBrightness] = useState('100%');
const [invert, setInvert] = useState("0%");
const [hue, setHue] = useState("0deg");
const [saturate, setSaturate] = useState("100%");
const [sepia, setSepia] = useState("0%");
const [grayscale, setGrayscale] = useState('0%');
const [rotation, setRotation] = useState("0deg");
const [width, setWidth] = useState('0');
const [height, setHeight] = useState('0');
const [color, setColor] = useState('black');
const container = {
display: 'grid',
gridTemplateColumns: 'auto auto auto',
gridTemplateRows: '80px 200px',
gridGap: '200px',
padding: '10px'
}
const settings = {
width: '200px',
maxHeight: '1000px'
}
const buttonStyle = {
height: '50px',
width: '200px'
}
const parametersStyle = {
height: '50px',
width: '100px',
marginBlockEnd: '0',
marginBlockStart: '0',
backgroundColor: 'rgba(46, 56, 79, 0.85)',
padding: '1em'
}
const imgStyle = {
width: '300px',
height: '300px',
transform: `rotate(${rotation})`,
filter: `sepia(${sepia}) grayscale(${grayscale}) hue-rotate(${hue}) saturate(${saturate}) invert(${invert}) contrast(${contrast}) brightness(${brightness})`,
color: color
}
const elementChangingStyle = {
maxWidth: '600px',
maxHeight: '600px'
}
const headerTitle = {
color: '#ffffff',
fontSize: '40px',
padding: '1em'
}
// thiw function but they are get only 50 and see
function onGrayscale (e, grayscale) {
let newGrey = grayscale;
console.log("this onGrayscale " + setGrayscale('50'));
}
return (
<div>
<div style={headerTitle}>
React Photo-Modifier <br/> with Hooks
</div>
<div style={container}>
<div style={settings}>
<ImageSlider
max={100}
value={grayscale}
onChange={e => setGrayscale(e.target.value)}
>
Grayscale {grayscale}
</ImageSlider>
</div>
<div style={elementChangingStyle}>
<div>
<span>
<img src={logo} className="App-logo" alt="logo" />
</span>
</div>
<img style={imgStyle} src={defaultImage} />
<p style={imgStyle} > {name}</p>
</div>
</div>
</div>
)
}
If I triggered function onGrayscale the I have only slide to 50 but I want do this dynamically? How to do?
If I set ImageSlider to target value then change to grayscale but I can't then change manually using the slider?
What I'm doing wrong?
EDIT 1:
This. it's working now! Under the function and return in return.
function onGrayscale (e, grayscale) {
setGrayscale(grayscale);
}
<ImageSlider
max={100}
value={grayscale}
onChange={onGrayscale}
>
Grayscale {grayscale}
</ImageSlider>
You aren't using the function arguments correctly in onGrayScale function. This function is only passed the value and not the event, so it would look like
function onGrayscale (grayscale) {
let newGrey = grayscale;
setGrayscale(grayScale);
}

Resources