You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用React+styled-components实现下拉菜单箭头翻转切换动画?

实现方案

你只需要对现有代码做两处核心调整即可满足需求:

  1. 给箭头组件添加带过渡效果的翻转受控样式
  2. (可选优化)修复当前下拉内容过渡不生效的问题(现有写法直接条件渲染会导致元素直接挂载卸载,过渡动画无法触发)

完整修改后代码如下:

import "./styles.css";
import styled from "styled-components";
import React, { useState, useCallback } from "react";
import { ArrowDown } from "./ArrowDown";

const Item = styled.div<{ active?: boolean }>`
  height: 40px;
  width: 300px;
  padding: 0px 30px;

  &:hover {
    background: #fafbfb;
  }
`;

const DropMenu = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #899098;
  width: 100%;
  height: 100%;
  font-size: 14px;
  font-weight: bold;
  gap: 12px;
  :hover {
    color: gray;
  }
  div {
    display: flex;
    align-items: center;
    gap: 12px;
  }
`;

const DropText = styled.div`
  padding-left: 32px;
`;

// 新增:带翻转过渡的箭头样式组件
const StyledArrow = styled(ArrowDown)<{ isOpen: boolean }>`
  transition: transform 0.3s ease;
  transform: ${props => props.isOpen ? 'rotate(180deg)' : 'rotate(0deg)'};
`;

// 新增:下拉容器样式,实现平滑展开收起
const DropContent = styled.div<{ isOpen: boolean }>`
  height: ${props => props.isOpen ? '80px' : '0'}; // 两个Item每个高40px,总高80px
  opacity: ${props => props.isOpen ? 1 : 0};
  overflow: hidden;
  transition: all 0.3s ease;
`;

export const App = () => {
  const [visible, setVisible] = useState(false);
  const handleDropVisibleChange = useCallback(() => {
    setVisible((prevVisible) => !prevVisible);
  }, []); // 这里依赖可以清空,因为用了函数式更新

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <Item onClick={handleDropVisibleChange}>
        <DropMenu>
          <div>
            <span>Menu</span>
          </div>
          {/* 替换原来的ArrowDown为带受控状态的StyledArrow */}
          <StyledArrow isOpen={visible} />
        </DropMenu>
      </Item>
      {/* 替换原来的条件渲染为受控样式的DropContent */}
      <DropContent isOpen={visible}>
        <Item>
          <DropMenu>
            <DropText>box1</DropText>
          </DropMenu>
        </Item>
        <Item>
          <DropMenu>
            <DropText>box2</DropText>
          </DropMenu>
        </Item>
      </DropContent>
    </div>
  );
};

export default App;

实现说明:

  • 箭头翻转通过transform: rotate实现,配合transition属性实现0.3s的平滑过渡效果,和目标交互体验一致
  • 下拉容器不再直接条件渲染,改为通过控制高度、透明度实现平滑展开收起,避免元素挂载卸载导致过渡失效
  • 箭头的翻转状态完全和visible变量绑定,状态同步不会出现错位

内容的提问来源于stack exchange,提问作者yuturo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 04:57:02