I am looking for something like this
<div className={`${next? setTimeout(() => 'shorten', 500) : ''}`}></div>
when next becomes true, add the 'shorten' class after 500ms
CodePudding user response:
You can use like this.
Add a state like this
const [myclass, setMyclass] = useState('');
//then define a function
function myFunction() {
setTimeout(()=> setMyclass('shorten') , 500)
}
In return stmt
{ if(next) myFunction;}
<div className={myClass}></div>
CodePudding user response:
This may be one possible solution to achieve the desired objective:
Code Snippet
const {useState} = React;
const SomeComp = () => {
const [next, setNext] = useState(false);
const [delayedFlag, setDelayedFlag] = useState(false);
return (
<div>
<div class={next ? 'redBg' : 'cyanBg'}>
Some Text
</div>
<div class={delayedFlag ? 'redBg' : 'cyanBg'}>
Some Text with delayed update
</div>
<button
onClick={() => setNext(prev => (!prev))}
>
Flip Color
</button>
<button onClick={
() => setTimeout(() => setDelayedFlag(prev => (!prev)), 500)
}>
Delayed Flip
</button>
<button
onClick={() => {
setNext(prev => (!prev));
setTimeout(
() => setDelayedFlag(prev => (!prev)),
750
);
}}
>
Flip Both Texts
</button>
</div>
);
};
ReactDOM.render(
<div>
DEMO
<SomeComp />
</div>,
document.getElementById('reactdiv')
);
.redBg { background-color: red; }
.cyanBg { background-color: cyan; }
<div id='reactdiv' />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
Explanation
- Two flags namely
next
anddelayedFlag
are declared withuseState
- Two buttons flip these flags.
- On the
delayedFlag
the buttononClick
delays the setting by 500ms - Thus, the two text blocks change styles differently. There is an observable delay in the style-change for the
delayedFlag
controlled text
EDIT
Added a third button to flip both texts, but one is immediate and the other is with a 750ms delay.
CodePudding user response:
I think useEffect
will be the correct way to do...
export default function App() {
const [cls, setCls] = useState("");
useEffect(() => {
if(!next) return;
let timeout = setTimeout(() => setCls("shorten"), 500);
return () => clearTimeout(timeout);
}, [next]);
return (
<div className={cls}>
</div>
);
}
Here is working snippet:
const {useEffect, useState} = React;
const App = () => {
const [cls, setCls] = useState("");
const [next, setNext] = useState(false);
useEffect(() => {
if (!next) return;
let timeout = setTimeout(() => setCls("shorten"), 500);
return () => clearTimeout(timeout);
}, [next]);
const resetClass = () => {
setCls("");
setNext(false);
};
return (
<div className="main">
<h3>Add class with delay</h3>
<div className={cls}>THIS DIV CHANGES CLASS</div>
<hr />
<button onClick={() => setNext(true)}>
Click to change "next" variable
</button>
<button onClick={() => resetClass()}>Clear Class</button>
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById("root")
);
.shorten {
background: red;
}
.main div{
border:1px solid #cccccc;
border-radius:3px;
padding:15px;
display:inline-block;
}
.main button{
background:#eaeaea;
border:1px solid #cccccc;
margin-right:15px;
padding:5px;
border-radius:3px;
cursor:pointer;
}
.main button:hover{
background:#f1f1f1;
}
.main button:active{
background:#f5f5f5;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>