首页 > 解决方案 > React Js 使用 useState 创建动画

问题描述

基本上我有以下问题我有一个状态开始为假,然后单击为真,每个真假状态都有不同的动画,但总是在组装组件时我已经开始动画并且我想开始动画只需点击一下

问题:

在此处输入图像描述

JSX

const NavMain = () => {
  const [isOpenBox, setOpenBox] = React.useState(false);
  console.log(isOpenBox);
  return (
    <Nav>
      <Container>
        <NavBetween>
          <WrapLogo>a</WrapLogo>
          <NavGrid>
            <NavUl isOpen={isOpenBox}>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <FontAwesomeIcon
                  onClick={() => setOpenBox(!isOpenBox)}
                  className="searchIcon"
                  rotation={90}
                  icon={faSearch}
                  size="1x"
                  fixedWidth
                  color="rgba(0, 0, 0, 0.08);"
                />
              </li>
            </NavUl>
            <SearchWrapper isOpen={isOpenBox}>
              <div className="FlexInput">
                <input placeholder="Pesquisar" />
                <div className="IconContainer">
                  <FontAwesomeIcon
                    onClick={() => setOpenBox(!isOpenBox)}
                    className="searchIcon"
                    icon={faTimes}
                    size="xs"
                    fixedWidth
                    color="black"
                  />
                </div>
              </div>
            </SearchWrapper>
          </NavGrid>
        </NavBetween>
      </Container>
    </Nav>
  );
};

JS 中的 CSS

const KeySearch = keyframes`
from { 
  z-index:2;
  visibility: visible; 
  transform: translateY(0); 
  opacity: 1;
 }
to   { 
  z-index:1;
  visibility: hidden; 
  transform: translateY(20px); 
  opacity: 0; display:none;
}
`;
const KeySearch2 = keyframes`
from {
  z-index:1;
  visibility: hidden; 
  transform: translateY(20px); 
  opacity: 0; display:none;

 }
to   { 
    z-index:2;
  visibility: visible; 
  transform: translateY(0); 
  opacity: 1;
}
`;
export const Nav = styled.nav`
  width: 100%;
  height: 80px;
  background: #fff;
`;
export const NavBetween = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 100%;
  width: 100%;
`;
export const Container = styled.div`
  height: 100%;
  margin: 0 auto;
  max-width: 80rem !important;
`;

export const NavGrid = styled.div`
  display: grid;
  width: 70%;
  height: 100%;
`;
export const NavUl = styled.ul`
  z-index: 2;
  grid-column: 1;
  grid-row: 1;
  display: flex;
  width: 100%;
  height: 100%;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  ${props =>
    props.isOpen
      ? css`
          animation: ${KeySearch} 0.5s;
          -webkit-animation-fill-mode: forwards;
          -moz-animation-fill-mode: forwards;
          -ms-animation-fill-mode: forwards;
          -o-animation-fill-mode: forwards;
          animation-fill-mode: forwards;
        `
      : css`
          animation: ${KeySearch2} 0.5s;
          -webkit-animation-fill-mode: forwards;
          -moz-animation-fill-mode: forwards;
          -ms-animation-fill-mode: forwards;
          -o-animation-fill-mode: forwards;
          animation-fill-mode: forwards;
        `}
  svg {
    cursor: pointer;
  }
  a {
    font-family: "Poppins", sans-serif;
    font-size: 0.8em;
    font-weight: bold;
    text-decoration: none;
    letter-spacing: 1px;
    display: block;
    color: rgba(0, 0, 0, 0.6);
    padding: 16px 20px;
    line-height: 24px;
    :hover {
      color: #cdcdcd;
      transition-duration: 0.5s;
      transition-property: background-color, color;
    }
  }
`;

export const WrapLogo = styled.div`
  width: 30%;
  img {
    height: 40px;
  }
`;

export const SearchWrapper = styled.div`
  grid-column: 1;
  grid-row: 1;
  visibility: hidden;
  opacity: 0;
  z-index: 1;
  display: flex;
  width: 100%;
  height: 100%;
  align-items: center;
  justify-content: flex-end;
  & .FlexInput {
    width: 100%;
    display: inline-flex;
    align-items: center;
    height: 100%;
    background: #fff;
    transition: all 0.4s;
    input {
      background: transparent;
      width: 100%;
      height: 100%;
      border: 0;
      padding: 0.5rem 0.8rem 0.5rem 1.2rem;
      outline: none;
      font-size: 14px;
      font-weight: 400;
      color: #a9a9a9;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      box-sizing: initial;
      font-family: "Poppins", sans-serif;
    }
  }
  & .IconContainer {
    display: flex;
    align-items: center;
    padding: 10px 0;
    width: 30px;
    cursor: pointer;
    :hover {
      color: white;
    }
  }
`;

例子

https://codesandbox.io/s/lucid-sammet-9qim9

标签: javascriptreactjs

解决方案


试试这个代码 -

import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import "./styles.css";
import {
  faSearch,
  faAdjust,
  faAngleDown
} from "@fortawesome/free-solid-svg-icons";
import { faTimes } from "@fortawesome/free-solid-svg-icons";
import {
  Container,
  Nav,
  NavBetween,
  WrapLogo,
  NavGrid,
  NavUl,
  SearchWrapper
} from "./styled";

const NavMain = () => {
  const [isOpenBox, setOpenBox] = React.useState(false);

  return (
    <Nav>
      <Container>
        <NavBetween>
          <WrapLogo>a</WrapLogo>
          <NavGrid>
            <NavUl isOpen={isOpenBox}>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <a href="#">Home</a>
              </li>
              <li>
                <FontAwesomeIcon
                  onClick={() => setOpenBox(!isOpenBox)}
                  className="searchIcon"
                  rotation={90}
                  icon={faSearch}
                  size="1x"
                  fixedWidth
                  color="rgba(0, 0, 0, 0.08);"
                />
              </li>
            </NavUl>
            {isOpenBox && (
              <SearchWrapper>
                <div className="FlexInput">
                  <input placeholder="Pesquisar" />
                  <div className="IconContainer">
                    <FontAwesomeIcon
                      onClick={() => setOpenBox(!isOpenBox)}
                      className="searchIcon"
                      icon={faTimes}
                      size="xs"
                      fixedWidth
                      color="black"
                    />
                  </div>
                </div>
              </SearchWrapper>
            )}
          </NavGrid>
        </NavBetween>
      </Container>
    </Nav>
  );
};

export default NavMain;


推荐阅读