Можете ли вы использовать встроенный ключевой кадр стилизованного компонента в компоненте?

#reactjs #styled-components

#reactjs #стилизованные компоненты

Вопрос:

Я пытаюсь создать эффект мерцающей звезды в своем приложении. Я создал массив и перебрал его, чтобы получить количество «звездочек» div , и я использовал стилизованные компоненты для оформления звездочек. Я пытаюсь анимировать каждый из них случайным образом, но для того, чтобы сделать это, я должен рандомизировать свойства в строке, когда divs создаются во время цикла. Попытка получить случайные значения в стилизованном компоненте дает одинаковое значение для каждого div. В настоящее время мой код выглядит следующим образом:

 import React from 'react';
import styled, { keyframes, css } from 'styled-components'
import styles from './Stars.module.scss'

const flicker = keyframes`
    0%,100% {
        opacity: 1;
    }
    50% {
        opacity: 0.2;
    }

`
const Star = styled.div`
    position: absolute;
    width: 5px;
    height: 5px;
    border-radius: 2px;
    background: white;
`
const StarContainer = styled.div`
    position: absolute;
    top: 0;
    left: 0;
    overflow: hidden;
    width: 100%;
    height: 100%;
`

const vpHeight = window.innerHeight;
const vpWidth = window.innerWidth;

const starCount = () => {
    const count = []
    for(let i = 1; i <= 300; i  ){
        count.push(i)
    }
    return count
}

const Stars = () => {
    return (
        <StarContainer id='star-container'>
            {starCount().map((star, i) => (
                <Star style={{
                    animation: `${Math.floor(Math.random() * 8)}s ${flicker} infinite`,
                    top: `${Math.floor(Math.random()*vpHeight)}px`,
                    left: `${Math.floor(Math.random()*vpWidth)}px`
                }} />
            ))}
        </StarContainer>
    );
}

export default Stars;
  

Однако это приводит к следующей ошибке: Error: It seems you are interpolating a keyframe declaration (gvlTRP) into an untagged string. This was supported in styled-components v3, but is not longer supported in v4 as keyframes are now injected on-demand. Please wrap your string in the css\ helper which ensures the styles are injected correctly. See https://www.styled-components.com/docs/api#css

Я не уверен, как поступить. Есть ли способ включить styled-component ключевой кадр во встроенные стили элементов?

Ответ №1:

Вероятно, лучше всего сохранить ключевые кадры статичными, а затем сделать что-то вроде этого:

 // keep the keyframes declaration static
const flicker = keyframes`
  /* etc. */
`;

const Star = styled.div`
  animation: ${flicker} infinite;
  animation-duration: ${props => props.animationDuration};
`;

// later...

<Star animationDuration={Math.random() * 8} />
  

Комментарии:

1. Это работает идеально, как и ожидалось! Я все еще не совсем уверен, в чем заключалась проблема с моим кодом, однако, не могли бы вы объяснить это для меня?

2. @JoshBangle Проблема в том, что ключевые кадры стилизованных компонентов плохо сочетаются с style реквизитом React; React ожидает объект, каждое свойство которого является свойством CSS с чистым строковым значением, благодаря чему keyframes фактически генерируется какой-то внутренний стилизованный объект Components. Когда вы интерполируете flicker внутри вашего styled.div объявления, стилизованные компоненты улавливают это и затем преобразуют в какое-то объявление анимации, но React не может сделать то же самое.