#javascript #reactjs #css-animations #styled-components #keyframe
#javascript #reactjs #css-анимации #styled-компоненты #ключевой кадр
Вопрос:
Я сталкиваюсь с проблемой, когда, если я отделяю свои дочерние компоненты от своего основного компонента, мои анимации ключевых кадров перестают работать.
Рассматриваемая анимация представляет собой простой расширяющийся контейнер, который воспроизводится каждый раз, когда изменяется содержимое контейнера.
Мой Abouts.js (основной компонент):
const About = React.forwardRef((props, ref) => {
const [ topic, setTopic ] = useState('react')
const [ logo, setLogo ] = useState(topicsList[0].logo)
const [ active, setActive ] = useState(0)
...
const handleTopicChange = (topic, index, logo) => {
setTopic(topic.toLowerCase())
setLogo(logo)
setActive(index)
}
//Creates buttons from a list of topics and adds the functionality to switch between them
const createButtons = () =>
topicsList.map((topic, index) => (
<Button
key={topic.name.toLowerCase()}
onClick={() => handleTopicChange(topic.name, index, topic.logo)}
active={active === index}
>
{topic.name.toLowerCase().includes('csharp') ? 'C#' : topic.name.toUpperCase()}
</Button>
))
...
//Renders the Container with content based on the topic hook which gathers content from an i18next file
const Topic = props => {
const value = props.value.includes('c#') ? 'csharp' : props.value
return (
<TopicContainer>
<TopicTitle
style={{ textAlign: 'left' }}
$color={props.theme === dark ? dark.colors[value] : light.colors[value]}
>
{t(`titles.about.${value}`)}
</TopicTitle>
<div dangerouslySetInnerHTML={{ __html: props.children }} />
</TopicContainer>
)
}
return(
...
{createButtons()}
<Topic theme={props.theme} value={topic}>
{t(`paragraphs.${topic}`)}
</Topic>
...
)
}
Мой styles.js (Файл стилизованных компонентов):
...
const expand = keyframes`
from {
transform: scale(0.5);
}
to {
transform: scale(1);
}
`
const expandAnimation = css`
animation: css`${expand} 300ms ease`;
`
const blogText = css`
font-size: ${props => props.theme.fonts.size.xs};
font-weight: ${props => props.theme.fonts.weight.normal};
color: ${props => props.theme.colors.neutralLight};
@media ${device.greaterThan.laptopLMin} {
font-size: ${props => props.theme.fonts.size.md};
}
`
export const TopicContainer = styled.div`
${expandAnimation};
${blogText};
width: 85%;
margin: 0 auto;
margin-bottom: 2rem;
amp; div {
width: 100%;
float: left;
}
amp; p {
width: 100%;
@media ${device.greaterThan.laptopLMin} {
width: 70%;
}
}
`
...
Теперь все работает отлично и так, как задумано. Проблема в том, что когда я перемещаю дочерний компонент (тема) за пределы его родительского компонента (О нем), мои анимации перестают работать (за исключением первого рендеринга, также известного как при обновлении страницы). Несмотря на то, что содержимое внутри контейнера меняется так же, как и раньше, и я не получаю никаких негативных сообщений в своей консоли.
Я бы указал, что использую стилизованные компоненты, но я попытался создать файл css для той же цели, на случай, если проблема как-то связана со стилизованными компонентами, но результат был тот же. Все работает отлично, пока мой дочерний элемент не выйдет…
Пожалуйста, дайте мне знать, если не хватает информации.
Ответ №1:
Для запуска анимации вам необходимо передать либо props.main, либо props.signature, чтобы перейти к стилизованному компоненту
const expandAnimation = css`
animation: ${props => (props.signature || props.main ? 'none' : css`${expand} 300ms ease;`)};
`const expandAnimation = css`
animation: ${props => (props.signature || props.main ? 'none' : css`${expand} 300ms ease;`)};
`
Ваш TopicContainer должен быть;
let isSignature=true;
let isMain=true;
<TopicContainer signature={isSignature} main={isMain}>
<TopicTitle
style={{ textAlign: 'left' }}
$color={props.theme === dark ? dark.colors[value] : light.colors[value]}
>
{t(`titles.about.${value}`)}
</TopicTitle>
<div dangerouslySetInnerHTML={{ __html: props.children }} />
</TopicContainer>
Поскольку я не нашел никаких ссылок на подпись или main, я создаю фиктивные переменные для передачи в качестве prop.
Комментарии:
1. Оба реквизита (подпись и основной) фактически используются явно для предотвращения анимации. Поскольку я использую этот контейнер и для статического блока на своей странице. Таким образом, я намеренно не передаю эти реквизиты в рассматриваемый контейнер. Мой оператор говорит, что если ни один из этих реквизитов не является истинным, тогда анимируйте.
2. Я отредактировал реквизит из представленного кода, чтобы избежать путаницы.
3. Если вы не возражаете, можете ли вы поделиться репозиторием или сутью, немного сложно разобраться в потоке