Reactjs - setState() make all texts of apps flickering - reactjs

In component A, I got some setState functions to update states when clicking on some element. What strange happens is that all texts of the whole app flicked. Component A is completed isolated from others. This only happens on Chrome, firefox works just fine :( please help
My MenuButton component code :
import React, { Component } from 'react';
import styled, { css } from 'styled-components';
const InsideLineCommon = styled.span`
position: absolute;
width: 100%;
height: 100%;
left: 0%;
&:after {
content: '';
width: 100%;
height: 100%;
position: absolute;
background: ${props => props.theme.colors.primary1};
}
&:before {
content: '';
width: 100%;
height: 100%;
position: absolute;
background: ${props => props.theme.colors.primary1};
}
`;
const InsideLine = InsideLineCommon.extend`
&:after {
left: -200%;
}
transition: left ${props => props.theme.animationTime};
left: ${props => (props.isHalfWidth ? '-100%' : '-200%')};
${props => props.isInitialMoving && css`
left: -50%;
`}
${props => props.isInitialMoving && props.isHalfWidth && css`
left: 100%;
`}
${props => props.isHorizontalBarsMoving && css`
left: 200%;
`}
${props => props.isCrossoverBarMoving && css`
left: -200%;
`}
${props => props.isHalfWidth && css`
&:after {
width: 50%;
}
&:before {
width: 50%;
left: -100%;
}
`}
`;
const CommonLine = styled.div`
width: 100%;
height: 15%;
position: absolute;
`;
const MiddleLine = CommonLine.extend`
top: calc(100% / 2 - 7.5%);
`;
const TopLine = CommonLine.extend`
top: 0px;
`;
const BottomLine = CommonLine.extend`
bottom: 0px;
`;
const Wrapper = styled.button`
width: 100%;
height: 100%;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
overflow: hidden;
cursor: pointer;
border-style: none;
background: transparent
padding: 0px;
&:focus {
outline: 0px;
}
`;
const CrossoverWrapper = styled.div`
width: 100%;
height: 100%;
position: absolute;
top: 0px;
display: flex;
flex-direction: column;
justify-content: center;
&:after {
content: '';
position: absolute;
width: 100%;
height: 15%;
background: ${props => props.theme.colors.primary1};
transform-origin: center;
transform: ${props => (props.isCrossoverBarMoving ? 'rotate(45deg) translate(0%)' : 'rotate(45deg) translate(-130%)')};
transition: ${props => (!props.isCrossoverBarMoving
? `transform ${props.theme.animationTime} 0s`
: `transform ${props.theme.animationTime} ${props.theme.animationTime}`)};
border-radius: 5px;
}
&:before {
content: '';
position: absolute;
width: 100%;
height: 15%;
background: ${props => props.theme.colors.primary1};
transform-origin: center;
transform: ${props => (props.isCrossoverBarMoving ? 'rotate(-45deg) translate(0%)' : 'rotate(-45deg) translate(130%)')};
border-radius: 5px;
transition : ${props => (!props.isCrossoverBarMoving
? `transform ${props.theme.animationTime} 0s`
: `transform ${props.theme.animationTime} ${props.theme.animationTime}`)};
}
`;
class MenuButton extends Component {
constructor(props) {
super(props);
this.state = {
isCrossoverBarMoving: false,
isHorizontalBarsMoving: false,
isInitialMoving: false,
};
this.handleMouseClick = this.handleMouseClick.bind(this);
this.handleMouseHover = this.handleMouseHover.bind(this);
}
componentDidMount() {
setTimeout(() => {
this.setState({
isInitialMoving: true,
});
}, 1000);
}
handleMouseClick() {
this.setState(prevState => ({
isCrossoverBarMoving: !prevState.isCrossoverBarMoving,
}));
}
handleMouseHover() {
this.setState(prevState => ({
isHorizontalBarsMoving: !prevState.isHorizontalBarsMoving,
}));
}
render() {
const { isHorizontalBarsMoving, isCrossoverBarMoving, isInitialMoving } = { ...this.state };
return (
<Wrapper
onClick={this.handleMouseClick}
onMouseEnter={this.handleMouseHover}
onMouseLeave={this.handleMouseHover}
>
<TopLine>
<InsideLine
isHorizontalBarsMoving={isHorizontalBarsMoving}
isCrossoverBarMoving={isCrossoverBarMoving}
isInitialMoving={isInitialMoving}
/>
</TopLine>
<MiddleLine>
<InsideLine
isHorizontalBarsMoving={isHorizontalBarsMoving}
isCrossoverBarMoving={isCrossoverBarMoving}
isInitialMoving={isInitialMoving}
/>
</MiddleLine>
<BottomLine>
<InsideLine
isHalfWidth
isHorizontalBarsMoving={isHorizontalBarsMoving}
isCrossoverBarMoving={isCrossoverBarMoving}
isInitialMoving={isInitialMoving}
/>
</BottomLine>
<CrossoverWrapper
isCrossoverBarMoving={isCrossoverBarMoving}
/>
</Wrapper>
);
}
}
export default MenuButton;
Whenever I click this component, the all texts of whole app did flickering :/

Related

Does anyone know how to fix this ?( Dynamic nth-child & after ) react-sass

I'm trying to figure it out, but I haven't been able to...
It's a list with information and it's really almost ready, but the nth-child:after style I can't make it dynamic with react.
My React component:
const PieList = ({ data, colors = [] }: IPieListProps) => {
return data.length > 1 ? (
data.map(( item, index ) => (
<div
key={item.name}
className={styles['pie-list']}
style={{
backgroundColor: colors[index%colors.length]
}}
>
<ul>
{
item.name === 'others'
? <li>Otros<span>{item.value}</span> </li>
: <li>{item.name}<span>{item.value}</span></li>
}
</ul>
</div>
))
) : ''
}`
.pie-list {
ul {
max-width: 240px;
li {
&::after {
content: '';
width: 8px;
height: 8px;
border-radius: 8px;
position: absolute;
left: 0;
top: 0;
bottom: 0;
margin: auto;
}
&:nth-child(1){
&::after {
background-color: $orion;
}
}
&:nth-child(2){
&::after {
background-color: #433F5C;
}
}
&:nth-child(3){
&::after {
background-color: #898798;
}
}
}
}
}
I am trying to get this result:
But I have this:
you should try this:
ul {
list-style: none;
}
ul li::before {
content: "\2022";
color: red;
font-weight: bold;
display: inline-block;
width: 1em;
margin-left: -1em;
}
I solved it with a package called "styled-components", but if someone has a better solution that doesn't involve a library that would be great.
const Bullet = styled.div`
max-width: 240px;
li{
position: relative;
margin-bottom: 10px;
padding-left: 14px;
font-size: 14px;
color: $orion;
display: flex;
align-items: center;
justify-content: space-between;
&::after {
content: '';
width: 8px;
height: 8px;
background-color: ${ props => props.bulletColor };
border-radius: 8px;
position: absolute;
left: 0;
top: 0;
bottom: 0;
margin: auto;
}
`
export const PieBanksList = ({ data, colors }: IPieBanksListProps) => {
return data.length > 1 ? (
data.map(( item, index ) => (
<div
key={item.name}
className={styles['pie-list']}
>
<Bullet
bulletColor={colors[index % colors.length]}
>
{
item.name === 'others'
? <li>Otros<span>{item.value}</span> </li>
: <li>{item.name}<span>{item.value}</span></li>
}
</Bullet>
</div>
))
) : <EmptyGraph />
}

Renaming button.jsx makes entire react web unable to compile

i've been tasked with renaming a Button.jsx file for my react web app into 'v2_button.jsx' however when I do so it makes the entire web app unable to compile as there are many times where 'Button' is called but not 'v2_button'. My question is how do I make it so that I can update the name of the jsx file and update every instance where the original Button.jsx is called into 'v2_button'?
Button.jsx file:
import styled from 'styled-components';
const Button = styled.Button`
display: flex;
align-items: center;
justify-content: center;
height: 50px;
width: 300px;
background: ${(props) => {
let bg;
if (props.disabled) {
bg = props.theme.colors.disabled.background;
} else if (props.color === 'secondary') {
bg = props.theme.colors.primary.main;
} else if (props.color === 'danger') {
bg = props.theme.colors.danger.main;
} else {
bg = props.theme.colors.white;
}
return bg;
}};
font-family: ${(props) => props.theme.font.font3.new};
font-size: 18px;
font-weight: ${(props) => props.theme.fontWeight.heavy_900};
letter-spacing: 0.105em;
color: ${(props) => {
let fontColor;
if (props.color === 'secondary') {
fontColor = props.theme.colors.textPrimary.light;
} else {
fontColor = props.theme.colors.textPrimary.purple.dark;
}
return fontColor;
}};
padding: ${(props) => {
let padding;
if (props.size !== 's') {
padding = '0 39px';
}
return padding;
}};
border-radius: 40px;
border: ${(props) =>
props.disabled
? `1px solid ${props.theme.colors.disabled.border}`
: 'none'};
white-space: nowrap;
transition: background ${(props) => props.theme.animations.short} linear;
:hover {
background: ${(props) => {
let bg;
if (props.disabled) {
bg = props.theme.colors.disabled.background;
} else if (props.color === 'secondary') {
bg = props.theme.colors.primary.light;
} else if (props.color === 'danger') {
bg = props.theme.colors.danger.light;
} else {
bg = props.theme.colors.secondary.light;
}
return bg;
}};
cursor: pointer;
}
`;
export default Button;
Example where Button is called:
import styled from 'styled-components';
import Button from "../../Button";
export const Wrapper = styled.div`
display: flex;
flex-direction: column;
`;
export const Container = styled.div`
display: flex;
flex-direction: column;
`;
export const NameContainer = styled.div`
width: 100%;
display: flex;
align-content: space-between;
flex-direction: row;
font-style: normal;
font-weight: ${(props) => props.theme.fontWeight.med_500};
font-size: ${(props) => props.theme.fontSize.med_16};
`;
export const List = styled.div`
display: flex;
`;
export const FieldLabel = styled.label`
height: 36px;
color: ${(props) => props.theme.colors.white};
font-family: ${(props) => props.theme.font.font1.demi};
margin: 0 0 25px 0;
text-align: center;
font-style: normal;
font-weight: ${(props) => props.theme.fontWeight.heavy_800};
font-size: ${(props) => props.theme.fontSize.large_28};
line-height: 50px;
`;
export const Selected = styled.label`
width: 158px;
height: 40px;
margin: 0 10px 20px 10px;
padding-top: 10px;
padding-left: 20px;
font-size: ${(props) => props.theme.fontSize.med_20};
color: ${(props) => props.theme.colors.white};
font-family: ${(props) => props.theme.font.font1};
caret-color: ${(props) => props.theme.colors.textSecondary.main};
:focus {
outline: none;
}
:focus-within {
box-shadow: inset 0px 0px 2px 1px
${(props) => props.theme.colors.textSecondary.main};
}
::placeholder {
color: ${(props) => props.theme.colors.textPrimary.light};
}
background: ${(props) => props.theme.colors.primary.main};
border: ${(props) => props.theme.borders.textSecondary};
border-radius: 4px;
`;
export const AddFieldButton = styled(Button)`
margin: 30px;
font-size: ${(props) => props.theme.fontSize.med_20};
color: ${(props) => props.theme.colors.textSecondary.main};
background: none;
width: 1px;
text-align: center;
`;
Compiling error I receive after changing Button.jsx to v2_button.jsx:
https://imgur.com/a/kC0AdmG
The best thing is to renamed all the imports.
But a 'workaround' to renaming all the imports could be:
Keep the Button.jsx
Instead of exporting the default implementation, import the implementation from v2_button.jsx file and re-export it from the Button.jsx file.
Thus, every import of Button.tsx will actually refer to the implementation of v2_button.tsx file.
Example:
Button_v1.tsx
const Button_v1 = () => (
<>Button v1</>
);
export default Button_v1;
Button_v2.tsx
const Button_v2 = () => (
<>Button v2</>
);
export default Button_v2;
Since all other files reference Button_v1 and you don't want OR can't update the imports, you could do this:
Button_v1.tsx (after)
import Button_v2 from "./Button_v2"; // <-- ADDED THIS
const Button_v1 = () => (
<>Button v1</>
);
// export default Button_v1; // <-- COMMENTED THIS
export default Button_v2; // <-- ADDED THIS

react transition effect not work after async thunk

Although I have updated the todo status, the checkbox effect is not working correctly, as if no effect has been applied, what could be the reason for this? I don't think there is a problem with the api file, but the api request is taking a long time.I think it's because css doesn't render again, I can't think of anything else..
Thank you for helping
import React from "react";
import { useDispatch } from "react-redux";
import { toggleTodos } from "../redux/slice/thunkActions";
import styled from "styled-components";
const Content = styled.div`
color: #fff;
text-transform: capitalize;
`;
const Options = styled.div`
display: flex;
align-items: center;
justify-content: center;
gap: 2rem;
`;
const EditButton = styled.button`
cursor: pointer;
background-color: #ff6b81;
padding: 0.7rem 2rem;
color: #fff;
border-radius: 0.5rem;
font-weight: bold;
`;
const InputWrapper = styled.label`
position: relative;
`;
const Input = styled.input`
position: absolute;
left: -99999px;
top: -99999px;
&:checked + span {
background-color: #1890ff;
transition: 1s;
&:before {
left: calc(100% - 0.2rem);
transform: translateX(-100%);
}
}
`;
const Slider = styled.span`
display: flex;
width: 5rem;
height: 2.5rem;
cursor: pointer;
border-radius: 10rem;
background-color: #fcebb6;
transition: background-color 0.4s;
&:before {
content: "";
position: absolute;
top: 0.2rem;
left: 0.2rem;
width: 2.1rem;
height: 2.1rem;
border-radius: 2.1rem;
transition: 1s;
background-color: #fff;
}
`;
const Todo = ({ todo }) => {
const dispatch = useDispatch();
const handleChange = (todo) => {
dispatch(toggleTodos(todo));
};
return (
<li>
<Content>{todo.content}</Content>
<Options>
<EditButton type="button">Edit</EditButton>
<InputWrapper htmlFor={`todoContent${todo.id}`}>
<Input
id={`todoContent${todo.id}`}
type={"checkbox"}
onChange={() => handleChange(todo)}
checked={todo && todo.isCompleted}
/>
<Slider />
</InputWrapper>
</Options>
</li>
);
};
export default Todo;

reactjs: I have no idea how to render these components with styled-components

render the BarItem and BarItemSelect inside the link when the is true, they are all set precisely an using a css class, now it's two components...
I don't see a way to do this
const S = {
BarItem: styled.a`
position: relative;
display: block;
height: 3rem;
text-decoration: none;
cursor: pointer;
border: 0;
`,
BarItemSelected: styled.a`
font-weight: 500;
color: var(--dark-text-color);
filter: invert(1);
&:after {
content: '';
position: absolute;
display: block;
width: 100%;
height: 5px;
background-color: white;
border-radius: 5px 5px 0 0;
bottom: 0;
#media (max-width: 63.8rem) {
color: var(--dark-text-color);
filter: invert(1);
background-color: #000;
top: 0;
border-radius: 0 0 5px 5px;
}
}
`,
const SmartLink = ({ href, test, children, ...props }) => {
const router = useRouter();
const isActive = test ? new RegExp(test, 'g').test(router.pathname) : false;
return (
<Link
href={href}
{...props}
>
<a
className={
isActive
? `${styles.barItem} ${styles.barItemSelected}`
: styles.barItem
}
>
{children}
</a>
</Link>
);
};
I can't solve this... does anyone have any suggestions on how I can do it?
The code above is not clear but I'll try to write a pattern in which styled components are used.
styled component
import styled from "styled-components";
const BarItem = styled.a `
position: relative;
display: block;
height: 3rem;
text-decoration:
none;
cursor: pointer;
border: 0;
`;
const BarItemSelected = styled.a`
font-weight: 500;
color: var(--dark-text-color);
filter: invert(1);
&:after {
content: '';
position: absolute;
display: block;
width: 100%;
height: 5px;
background-color: white;
border-radius: 5px 5px 0 0;
bottom: 0;
#media (max-width: 63.8rem) {
color: var(--dark-text-color);
filter: invert(1);
background-color: #000;
top: 0;
border-radius: 0 0 5px 5px;
}
}
`;
Then in the component
import { NavLink} from "react-router-dom";
return (
<NavLink className={isActive
? BarItemSelected
: BarItem} to={href}>
>
{children}
</a>
</NavLink>
);
Please try the above code, if it does'nt work please comment, I'll make the neccessary changes.

Range Slider with React and Typescript

I have created range slider but when we change the min value then it will not work. I want dynamic range Slider with ticks and moving label with respect to thumb without using any package.
This is my code below. i am expecting to create a dynamic range slider without using any package and also slider have ticks and movable thumbs which shows value with respect to thumbs
import { useCallback } from 'react';
import { Styles } from './range-slider-style';
interface IVersionSliderProps {
latestVersion: number;
olderVersion: number;
onChange: (val: any) => void;
}
export function VersionSlider(props: IVersionSliderProps) {
const setValue = useCallback((e) => {
console.log(e.target.value);
const newVal = e.target.value;
const negNewVal = -10 * Number(newVal);
console.log(negNewVal);
(document.querySelector('.range-text') as HTMLDivElement).style.left = (newVal + '%'); //Set range left position
(document.querySelector('.range-text') as HTMLDivElement).style.transform = 'translate(' + negNewVal + '%, 20px)'; //Set range translate to correct
(document.querySelector('.range-text') as HTMLDivElement).innerHTML = newVal; //Set range text equal to input position
}, []);
return (
<Styles>
<div className="input-container">
<input
id='#input'
type="range"
min={olderVersion}
max={latestVersion}
//value="1"
onChange={setValue}
step='.01' />
<div className="range-text">0</div>
</div>
</Styles>
);
}
//Css part below:
import styled from 'styled-components';
export const Styles = styled.div`
align-items: center;
display: "flex";
height: 100px;
color: #888;
margin-top: 2rem;
flex-direction:column;
margin-bottom: 2rem;
width: 1200px;
.value {
font-size: 1rem;
}
.input-container {
position: relative;
height:10px;
display: flex;
background: border-box;
width: 100%;
padding: 0;
}
.marking {
height:20xp;
widht:100%;
background-color: "black";
margin-top: 20px;
}
input[type="range"] {
appearance: none;
background-color: #56B0C9;
width: 100%;
height: 8px;
padding: 0;
}
input[type="range"]::-webkit-slider-thumb {
-moz-appearance: none !important;
appearance: none !important;
position: relative;
height: 20px;
width: 100px;
background: transparent;
cursor: ew-resize;
z-index: 2;
}
input[type="range"]::-moz-range-thumb {
-moz-appearance: none !important;
appearance: none !important;
position: relative;
height: 20px;
width: 100px;
background: transparent;
cursor: pointer;
z-index: 2;
}
.range-text {
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
background: white;
text-align: center;
line-height: 1;
height: 18px;
width: 60px;
transform: translate(0, 2px);
}`;

Resources