Я хочу воспроизвести эффект, который я закодировал в этом пример ванильного JS, в моем приложении React.
Это мой Сасс
.item
opacity: 0
transition-property: opacity
transition-timing-function: ease-in
.is-transitioning
opacity: 1
цикл, генерирующий изображения и их контейнеры:
this.props.images.map((image, index) => <ImageContainer key = {`img-${index}`}
image = {image}
transitionDuration = {Math.trunc(index * Math.random() * 1000) + 200} />
)
и, наконец, компонент ImageContainer:
const ImageContainer = (props) => (
<div className = "item is-transitioning"
style = {{ transitionDuration: `${props.transitionDuration}ms` }}
>
<img src = {`${props.image.path}`} />
</div>
);
export default ImageContainer;
Несмотря на то, что встроенный класс применяется правильно и есть css, я не могу понять, почему эффект не проявляется.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Проблема в том, что is-transitioning добавляется с самого начала, поэтому ваши элементы уже находятся на opacity:1 и ничего не произойдет. Вам нужно добавить класс, чтобы вызвать изменение непрозрачности и увидеть переход.
Другой способ, если вы не можете добавить класс, — использовать анимацию. Вот пример JS, который вы можете преобразовать в реакцию:
Array.from(document.querySelectorAll('.item')).map((i, index) => {
i.style.animationDuration = `${(index * Math.trunc(Math.random() * 1000)) + 200}ms`;
});.container {
display: flex;
}
.item {
display: flex;
justify-content:center;
align-items: center;
width: 1rem;
height: 1rem;
background-color: teal;
padding: 2rem;
margin-right: 1.2rem;
border-radius: 10px;
font-size: 2rem;
color: white;
opacity: 0;
animation:change 2s forwards;
}
@keyframes change{
to {
opacity:1;
}
}<div class = "container">
<div class = "item">1</div>
<div class = "item">2</div>
<div class = "item">3</div>
<div class = "item">4</div>
<div class = "item">5</div>
</div>Просто сохраните тот же код, который вы написали, замените transitionDuration на animationDuration и настройте CSS.
(Как сказано в другом ответе на этот поток) Проблема в том, что CSS (классы) не изменились, поэтому переход «не нужен», не вызывая анимации.
Для пользователей React, которые хотят использовать переход вместо анимации или других библиотек, вот «рабочая» рабочий пример с грязный взлом: https://jsfiddle.net/s16nd2j5/
Хитрость заключается в том, чтобы добавить класс к <ImageContainer> в componentDidMount() с setTimeout для 0 мс.
setTimeout( _ => this.setState({ transitioning: true }), 0);
Это своего рода заставляет обновление состояния быть «отложенным» до другого рендеринга, что приводит к «изменению класса CSS».
P.S. это взлом. Код пахнет, когда setTimeout / setInterval используется вот так.
П.П.С. Часть shuffle() из скрипки OP для простоты опущена.
Прежде чем попробовать ваше решение, я действительно попытался добавить класс css
is-transitioningвcomponentDidMount()родительского компонента, но это тоже не сработало. Я думаю, что с моей стороны было концептуально неправильно предполагать, что я увижу переход, когда элемент был добавлен в класс с самого начала. Спасибо, ваше решение работает как шарм.