Javascript 在react中渲染时,如何向对象添加过渡?
因此,我将我的代码设置为在特定钩子设置为true的条件下,在组件中呈现到HTML中。我还设置了css转换,但因为当元素设置为true时,css.open会在完全相同的时间触发,它不起作用。我如何解决这个问题?我已经研究了定时延迟,但它们似乎也不起作用Javascript 在react中渲染时,如何向对象添加过渡?,javascript,html,css,reactjs,Javascript,Html,Css,Reactjs,因此,我将我的代码设置为在特定钩子设置为true的条件下,在组件中呈现到HTML中。我还设置了css转换,但因为当元素设置为true时,css.open会在完全相同的时间触发,它不起作用。我如何解决这个问题?我已经研究了定时延迟,但它们似乎也不起作用 //hooks set state const [mealOne_box, mealOne_boxSet] = useState(false); const [box_transition, setbox_transitio
//hooks set state
const [mealOne_box, mealOne_boxSet] = useState(false);
const [box_transition, setbox_transition] = useState(false);
const [scroll, scrollSet] = useState(false);
//stops body from scrolling behind popup
if (scroll) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = 'unset';
}
//handles clicks for popup
const mealOneClickHandler = (event) => {
mealOne_boxSet(!mealOne_box);
scrollSet(!scroll)
setbox_transition(!box_transition)
}
//popup element
{mealOne_box && (
<div className='meal_popup'>
<div className={box_transition ? 'meal_popupElement open' : 'meal_popupElement'}>
<CancelIcon onClick={mealOneClickHandler} />
<img alt='' src={PancakeImage} />
<div className='text_scroll'>
<h2>Method:</h2>
<p>blablabla</p>
</div>
</div>
<div onClick={mealOneClickHandler} className='meal_popupBackground' />
</div>
)}
//css
.meal_popupElement {
position: fixed;
margin: auto;
margin-top: 6%;
width: 95%;
left: 50%;
transform: translateX(-50%);
background: white;
border-radius: 15px;
height: 80%;
box-shadow: 0px 2px 1px -1px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14),
0px 1px 3px 0px rgba(0, 0, 0, 0.12);
z-index: 2;
overflow: hidden;
p,
h2 {
padding-left: 1rem;
padding-right: 1rem;
font-family: "Open Sans", sans-serif;
}
p {
margin-top: 0;
}
h2 {
margin-bottom: 0.5rem;
font-size: larger;
}
svg {
position: absolute;
display: flex;
margin: 6px;
width: auto;
height: 35px;
color: white;
right: 0;
}
img {
width: 100%;
height: 30%;
object-fit: cover;
object-position: 0% 0%;
}
transition: opacity .25s ease-in-out;
opacity: 0;
}
.meal_popupElement.open {
opacity: 1;
}**
//挂钩设置状态
const[mealOne\u box,mealOne\u boxSet]=useState(false);
const[box\u transition,setbox\u transition]=useState(false);
const[scroll,scrollSet]=useState(false);
//阻止正文在弹出窗口后滚动
如果(滚动){
document.body.style.overflow='hidden';
}否则{
document.body.style.overflow='unset';
}
//处理弹出窗口的单击
const mealOneClickHandler=(事件)=>{
mealOne_箱集(!mealOne_箱);
滚动设置(!滚动)
setbox\u转换(!box\u转换)
}
//弹出元素
{mealOne_box&&(
方法:
喋喋不休
)}
//css
1.套餐{
位置:固定;
保证金:自动;
利润率最高:6%;
宽度:95%;
左:50%;
转化:translateX(-50%);
背景:白色;
边界半径:15px;
身高:80%;
盒子阴影:0px 2px 1px-1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),
0px 1px 3px 0px rgba(0,0,0,0.12);
z指数:2;
溢出:隐藏;
P
氢{
左:1rem;
右侧填充:1rem;
字体系列:“开放式Sans”,无衬线;
}
p{
边际上限:0;
}
氢{
边缘底部:0.5雷姆;
字体大小:较大;
}
svg{
位置:绝对位置;
显示器:flex;
利润率:6px;
宽度:自动;
高度:35px;
颜色:白色;
右:0;
}
img{
宽度:100%;
身高:30%;
对象匹配:覆盖;
对象位置:0%0%;
}
过渡:不透明度。25秒缓进缓出;
不透明度:0;
}
.fine_popupElement.open{
不透明度:1;
}**
我修复了淡入淡出功能:
<div className= {mealOne_box ? 'meal_popup': 'meal_popup hidden'}>
<div className={box_transition ? 'meal_popupElement open' : 'meal_popupElement'}>
<CancelIcon onClick={mealOneClickHandler} />
<img alt='' src={PancakeImage} />
<div className='text_scroll'>
<h2>Ingredients:</h2>
<p>{Math.round((mealOneCals * 0.45) / 3.64)}g of flour, 1.5 teaspoons of baking powder, {Math.round((mealOneCals * 0.2) / 3.68)}g of cocoa powder, water, calorie free sweetener, {Math.round((mealOneCals * 0.05) / 0.67)}g of mixed berries and {Math.round(((mealOneCals * 0.3) / 1.55) / 44)} medium eggs.</p>
<p>High protein and low calorie dense option: use {Math.round((mealOneCals * 0.55) / 3.64)}g of flour and {Math.round((mealOneCals * 0.2) / 0.45)}ml of egg white instead(this is less calorie dense so you get more food for the same amount of calories along with it being much higher in protein).</p>
<h2>Method:</h2>
<p>Combine the flour, egg, baking powder, cocoa together in a bowl to make a thick batter(add sweetener to taste). Then add as much water required to give the batter a pourable consistency. Pre heat a good non-stick pan on medium heat with no oil, once up to heat pour in your batter and flip once ready. Once all pancakes are made serve with fruit on-top.</p>
</div>
</div>
<div onClick={mealOneClickHandler} className='meal_popupBackground' />
</div>
您需要您的组件来呈现
.popup
,然后,一旦它已经在DOM中,就添加.open
类,以便转换工作
在代码中进行最小更改的一种方法是在or调用中包装setbox\u transition(!box\u transition)
,以确保mealOne\u box
和box\u transition
不会同时更新,并触发两个单独的请求
但是,由于setState
是异步的,这可能仍然不起作用,或者可能很难找到setTimeout
的正确延迟,因为React可能会决定批处理您的更新,并且仍然同时执行DOM更新
这可能会起作用,但这种延迟相当大:
const mealOneClickHandler = (event) => {
mealOne_boxSet(!mealOne_box);
scrollSet(!scroll);
setTimeout(() => {
setbox_transition(!box_transition);
}, 1000);
};
requestAnimationFrame
可能需要添加两次,但问题仍然比setTimeout
严重:
const mealOneClickHandler = (event) => {
mealOne_boxSet(!mealOne_box);
scrollSet(!scroll);
requestAnimationFrame(() => {
requestAnimationFrame(() => {
setbox_transition(!box_transition);
});
});
};
所以最好的解决办法就是使用。你可以看一看,我认为这比官方文件更容易理解。谢谢你的朋友,这真是太棒了。你认为这是一个比我自己发布的更好的解决方案吗?这会允许淡出动画吗?我目前的方法不起作用。是的,你的解决方案无法扩展。可以使用
opacity:0
和pointer events:none
(或类似内容)在页面上永久呈现一些小组件,然后添加一个open
类来还原这些组件,但假设您有一个内部有巨大表单的模态。在用户真正想要打开它之前,您肯定不想渲染它,所以您需要找到一种方法,在使用过渡淡入淡出组件时,有条件地渲染组件。@lukeetreactcstransitiongroup
是的,这是正确的使用方法。其他东西只是一个变通方法,让你明白为什么它现在不起作用。好的,非常感谢你的帮助,非常感谢你的帮助,两种方法都有效,但是你的权利更好的方法是尽可能少的元素渲染
const mealOneClickHandler = (event) => {
mealOne_boxSet(!mealOne_box);
scrollSet(!scroll);
requestAnimationFrame(() => {
requestAnimationFrame(() => {
setbox_transition(!box_transition);
});
});
};