I was going to the react router code here: modal-gallery
and came across this syntax
const Modal = ({ match, history }) => {
const image = IMAGES[parseInt(match.params.id, 10)]
if (!image) {
return null
}
const back = (e) => {
e.stopPropagation()
history.goBack()
}
return (
<div
onClick={back}
style={{
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
background: 'rgba(0, 0, 0, 0.15)'
}}
>
<div className='modal' style={{
position: 'absolute',
background: '#fff',
top: 25,
left: '10%',
right: '10%',
padding: 15,
border: '2px solid #444'
}}>
<h1>{image.title}</h1>
<Image color={image.color} />
<button type='button' onClick={back}>
Close
</button>
</div>
</div>
)
}
My Question is, what type of syntax is this? and how would you convert this into ES6 React.Component class
it is a React Stateless Functional Component (React SFC). It's a function, instead of a class.
Basically you don't need/have to convert it to a React.Component class as it's a valid way to declare a React.Component.
A SFC is normally referred to as a dumb component, as it only care about the props passed to it but nothing else. It's a component that is pure (it is not supposed to have any internal state) nor should have any side effects come out from its lifecycle functions.
React recommends that if you don't need internal state, nor lifecycle methods with your component, you should write it as a SFC.
You can have a further look here:
https://reactjs.org/docs/components-and-props.html
This is a pure function. You can look at it as just the render function of a React.Component.
Converting it then becomes easy, just paste the code inside you render function:
class Modal extends React.Component {
render() {
const { match, history } = this.props; // Here you get your props
const image = IMAGES[parseInt(match.params.id, 10)]
if (!image) {
return null
}
const back = (e) => {
e.stopPropagation()
history.goBack()
}
return (
<div
onClick={back}
style={{
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
background: 'rgba(0, 0, 0, 0.15)'
}}
>
<div className='modal' style={{
position: 'absolute',
background: '#fff',
top: 25,
left: '10%',
right: '10%',
padding: 15,
border: '2px solid #444'
}}>
<h1>{image.title}</h1>
<Image color={image.color} />
<button type='button' onClick={back}>
Close
</button>
</div>
</div>
)
}
}
Related
I'm working on a react. The code below is an example. ArrayExample is mapped and returned to the div component. Whenever I click the mapped div component, I want to change the value of the top of div (position: 'absolute') and place it on the right side according to the mapped div topBorder. Is there a way? I want to move it smoothly like an animation.
import React from "react";
const sample = () => {
const arrayExample = ["AAAA", "BBBB", "CCCC"];
return (
<div
style={{
display: "flex",
flexDirection: "column",
width: "100%",
height: "500px",
alignItems: "center",
justifyContent: "center",
backgroundColor: "#f3f3f3",
}}
>
{arrayExample.map((v, i) => {
return (
<div
style={{
width: "50%",
padding: 50,
border: "1px solid black",
marginTop: 15,
}}
onClick={() => {
console.log("Event!")
}}
>
{v}
</div>
);
})}
<div style={{position: 'absolute', top: 70, right: '22%', backgroundColor: "#4285F4", width: 50, height: 150, borderRadius: 5}}>
moving screen(I want to Change top value)
</div>
</div>
);
};
export default sample;
On click of the item div, you need to figure out the distance of that div from the top, and then change the top css property of your right div according to that. To find this distance you can use offsetTop property. For animation you can use transition property. Here is the code:
import React, { useRef } from "react";
const Sample = () => {
const arrayExample = ["AAAA", "BBBB", "CCCC"];
const rightDiv = useRef();
const itemClickHandler = (i) => {
const newTopHeight = document.getElementById("container").children[i].offsetTop;
rightDiv.current.style.top = newTopHeight + 'px';
}
return (
<div
id="container"
style={{
display: "flex",
flexDirection: "column",
width: "100%",
height: "500px",
alignItems: "center",
justifyContent: "center",
backgroundColor: "#f3f3f3",
}}
>
{arrayExample.map((v, i) => {
return (
<div
key={i}
style={{
width: "50%",
padding: 50,
border: "1px solid black",
marginTop: 15,
}}
onClick={() => itemClickHandler(i)}
>
{v}
</div>
);
})}
<div
ref={rightDiv}
style={{
position: 'absolute',
top: 70,
right: '22%',
backgroundColor: "#4285F4",
width: 50,
height: 150,
borderRadius: 5,
transition: "top 0.5s ease-in-out"
}}>
moving screen(I want to Change top value)
</div>
</div>
);
};
export default Sample;
You can see this in action here: https://codesandbox.io/s/thirsty-curie-7mskj
In your click handler you can get the current position of the clicked div in px, you can easily google how to do this this (relative to the page, not the viewport). I would suggest storing this value in state, call it something like activeItemOffsetTop, then just set top to the current state
I'm facing this issue in which if I don't wrap an element with CSS transition into a React child component then it runs the transition smoothly and if I wrap it into a child component it doesn't show the transition at all.
App.js
...
const [pb, setPb] = React.useState("0");
if (pb == 0) {
setTimeout(() => {
setPb("60");
}, 1000);
}
const AnotherBall = () => {
return (
<div
className="ball2"
style={{
top: `${pb}%`
}}
></div>
);
};
return (
<div className="App">
<div
className="ball"
style={{
top: `${pb}%`
}}
></div>
<AnotherBall />
</div>
);
style.css
...
.ball,
.ball2 {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: #ff5f5f;
border-radius: 50%;
transition: all 1s ease-in-out;
}
.ball2 {
left: 90%;
background: #ff5f5f;
}
sandbox: https://codesandbox.io/s/boring-wescoff-jcxgw?file=/src/App.js
Don't declare components inside the body of other components. Every time a component rerenders the functions it contains are redeclared, meaning they are not referentially stable from one render to the next. AnotherBall in your example is being unmounted and remounted with the new value because React thinks it's a new component.
Instead, move the component outside of App and pass the required value as a prop like this:
// App.js
<AnotherBall pb={pb} />
// AnotherBall.js
const AnotherBall = ({pb}) => {
return (
<div
className="ball2"
style={{
top: `${pb}%`
}}
></div>
);
};
Im stuck on a simple error, but just can't find it.
I have created an const, too style an element. Now I want to put the constant into the CSS, but somehow that doesn't work.
I want delete this line:
<div style={OVERLAY_STYLES}/>
Can somebody explain my mistake?
const OVERLAY_STYLES = {
position: "fixed",
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: "rgba(0,0,0, .7)",
zIndex: 1000,
};
export default function Modal({ open, children, onClick }) {
const [check, setCheck] = useState([]);
......
return ReactDOM.createPortal(
<div className="OVERLAY_STYLES">
<div style={OVERLAY_STYLES}/>
<div className="MODAL_STYLES">
<h1>Blabla.</h1>
{attribute.map((att, index) => {
return (
<div>
......
</div>
);
})}
<div className="b01">
<button onClick={() => onClick(check)} >Submit</button>
</div>
</div>
</div>
,
document.getElementById("portal")
);
}
.OVERLAY_STYLES {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0, .7);
z-index: 1000;
};
In react inline styling, all values need to be inside ' ' . Change your OVERLAY_STYLES code to:
.OVERLAY_STYLES {
position: 'fixed';
top: '0';
left: '0';
right: '0';
bottom: '0';
backgroundColor: 'rgba(0,0,0, .7)';
z-index: '1000';
};
also, no dashes so change background-color to backgroundColor
Root Cause:-
You are wrapping your <div style={OVERLAY_STYLES}/> under <div className="OVERLAY_STYLES">.
You are using the same style on both div tags which have z-index applied with the same value. So in your case:- with inline-style is appearing above the parent div by hiding it under itself.
I am attaching the snippet have a look for the reference:-
const OVERLAY_STYLES = {
position: "fixed",
top: 20,
left: 20,
right: 20,
bottom: 20,
backgroundColor: "red",
zIndex: 1000,
color:"white",
width:"50%",
};
const App = () => /*#__PURE__*/React.createElement("div", {
className: "OVERLAY_STYLES"
}, /*#__PURE__*/React.createElement("div", {
style: OVERLAY_STYLES
}, "hELLO"));
ReactDOM.render( /*#__PURE__*/React.createElement(App, null), document.getElementById("app"));
.OVERLAY_STYLES{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: ;
background-color: yellow;
z-index: 1000;
color:green;
width:100vw;
height:700px;
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
Solution:-
Try changing z-index/width.
Note:-Element with higher z-index will be at the top.
I have a reusable component that contains an animation called AnimationLoader. This component is a reusable component for loading states. I'm simply trying to take this component and use it inside of another component, UnpublishBlogBtn as the loader after a button click - that all works fine. However, I'd like to change the height and width of the animation inside of UnpublishBlogBtn and cannot for the life of me get that to work properly.
I've tried implementing Object.assign to bring in the CSS from the other file and just change the height and width. I've also tried just changing the CSS by doing <style={{}}> as well as wrapping the component in a div that has a style added(this appears to just change the button and not the animation itself).
<Button type="main" className="blogBtn">
{currentlyUnpublishingBlog ? <AnimatedLoader css={{ height: 1, width: 1 }}/> :
'Unpublish Blog'}
</Button>
const AnimatedLoader = () => {
return (
<div
css={{
height: 45,
width: 45
}}
>
<AnimatedIcon
css={{
animationDelay: '0.7s',
height: 35,
left: 10,
position: 'absolute',
top: 10,
width: 35
}}
/>
<AnimatedIcon
css={{
animationDelay: '0.7s'
display: 'none',
height: 45,
left: 0,
top: 0,
width: 45,
}}
/>
<div
css={{
borderRadius: 20,
borderStyle: 'solid',
borderWidth: 3,
height: 45,
position: 'absolute',
width: 45,
}}
/>
</div>
)
};
export default AnimatedLoader;
After user clicks on Unpublish Blog button, the loader should display as a smaller width and height on top of the button. Currently, it maintains the same size as what is listed inside of AnimatedLoader component and I'd like the size to change inside of the UnpublishBlogBtn component.
You can pass your css in as a prop to your AnimatedLoader
const AnimatedLoader = ({css={
height: 45,
width: 45
}}) => {
return (
<div
{...css}
>
<AnimatedIcon
css={{
animationDelay: '0.7s',
height: 35,
left: 10,
position: 'absolute',
top: 10,
width: 35
}}
// ....
If you need to do more complex things, it's probably more sensible to pass in a prop that describes the different style options as a group. So isSmallSize as a boolean or different sizes as an enum etc.
Then in your component you adjust the styles depending on the prop.
const AnimatedLoader = ({ isSmallSize = false }) => {
const outerSize = isSmallSize ?
{ height: 45, width: 45 } : { height: 1, width: 1 }
const iconSize = isSmallSize ?
{ height: 35, width: 35 } : { height: 1, width: 1 }
return (
<div css={{ ...outerSize }}>
<AnimatedIcon
css={{
animationDelay: '0.7s',
left: 10,
position: 'absolute',
top: 10,
...iconSize
}}
/>
<AnimatedIcon
css={{
animationDelay: '0.7s',
display: 'none',
left: 0,
top: 0,
...iconSize
}}
/>
<div
css={{
borderRadius: 20,
borderStyle: 'solid',
borderWidth: 3,
position: 'absolute',
...iconSize
}}
/>
</div>
)
}
Somehow react native zIndex fails to work on this piece of code...
<View>
<View style={{backgroundColor: 'red', width: 100, height: 100, zIndex: 1, position: 'absolute', top: 0, right: 0}}/>
<View style={{backgroundColor: 'blue', width: 50, height: 50, zIndex: 0, position: 'absolute', top: 0, right: 0}}/>
</View>
If anyone can explain to me why this is "not working" that would be great!
(btw, this is on Android React-native version 0.45.1)
This is my workflow atm:
index.android.js
import React from 'react-native';
import Viewport from './app/Viewport';
React.AppRegistry.registerComponent('TSK', () => Viewport);
Viewport.js
import React, { Component } from 'react';
import {
AppRegistry,
View,
StyleSheet
} from 'react-native';
// Viewport
export default class Viewport extends Component {
render() {
return (
<View>
<View style={{backgroundColor: 'red', width: 100, height: 100, zIndex: 1, position: 'absolute', top: 0, right: 0}}/>
<View style={{backgroundColor: 'blue', width: 50, height: 50, zIndex: 0, position: 'absolute', top: 0, right: 0}}/>
</View>
);
}
}
AppRegistry.registerComponent('Viewport', () => Viewport);