You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React水平滚动菜单左侧箭头至Item1多余空白的解决求助

I've looked at your code and spotted a few issues that are causing that unwanted space between the left arrow and the first item. Let's fix them step by step:

1. Incorrect Arrow Component Initialization

You're directly invoking the Arrow function instead of using it as a React component. This bypasses React's component lifecycle and can lead to layout inconsistencies. Replace your arrow definitions with proper JSX syntax:

// Replace these lines
const ArrowLeft = Arrow({ text: '<', className: 'arrow-prev' });
const ArrowRight = Arrow({ text: '>', className: 'arrow-next' });

// With this:
const ArrowLeft = () => <Arrow text="<" className="arrow-prev scroll-menu-arrow" />;
const ArrowRight = () => <Arrow text=">" className="arrow-next scroll-menu-arrow" />;

2. Wrong Selected Prop Logic for Menu Items

Your Menu component is passing the entire selected string to every MenuItem instead of checking if the current item's name matches the selected key. This causes incorrect styling and potential layout shifts. Update the Menu function:

export const Menu = (list, selected) => list.map(el => {
  const { name } = el;
  // Check if current item's name matches the selected key
  return <MenuItem text={name} key={name} selected={name === selected} />;
});

3. Stale Menu Items in Constructor

You're initializing menuItems in the constructor, which only runs once. When the selected state changes, the menu won't re-render with updated active states. Move the menu generation to the render method:

render() {
  const { selected } = this.state;
  // Generate menu items dynamically in render to reflect state changes
  const menu = Menu(list, selected);

  return (
    <div className="App">
      <ScrollMenu
        data={menu}
        arrowLeft={ArrowLeft}
        arrowRight={ArrowRight}
        selected={selected}
        // Fix onSelect to pass the selected key correctly
        onSelect={this.onSelect}
      />
    </div>
  );
}

4. Default Container Padding from the Library

The react-horizontal-scrolling-menu library adds default padding to the scroll container. Add this CSS to remove it:

/* Add to App.css */
.scroll-menu-container {
  padding-left: 0 !important;
  padding-right: 0 !important;
}

5. Fix Initial Selected Value & onSelect Method

Your initial selected value points to item1, which doesn't exist in your list (your first item is item01). Also, the onSelect method wasn't receiving the selected key. Update these parts:

// Update initial selected value
const initialSelected = 'item01';

class AppList extends Component {
  state = { selected: initialSelected };

  // Fix onSelect to receive and use the key
  onSelect = (key) => {
    this.setState({ selected: key });
  }

  // ... rest of the component
}

Full Modified AppList.js

import React, { Component } from 'react';
import ScrollMenu from 'react-horizontal-scrolling-menu';

const list = [
  { name: 'item01' },
  { name: 'item2' },
  { name: 'item3' },
  { name: 'item4' },
  { name: 'item5' },
  { name: 'item6' },
  { name: 'item7' },
  { name: 'item8' },
  { name: 'item9' }
];

const MenuItem = ({ text, selected }) => {
  return <div className={`menu-item ${selected ? 'active' : ''}`}>{text}</div>;
};

export const Menu = (list, selected) => list.map(el => {
  const { name } = el;
  return <MenuItem text={name} key={name} selected={name === selected} />;
});

const Arrow = ({ text, className }) => {
  return (
    <div className={className}>{text}</div>
  );
};

const ArrowLeft = () => <Arrow text="<" className="arrow-prev scroll-menu-arrow" />;
const ArrowRight = () => <Arrow text=">" className="arrow-next scroll-menu-arrow" />;

const initialSelected = 'item01';

class AppList extends Component {
  state = { selected: initialSelected };

  onSelect = (key) => {
    this.setState({ selected: key });
  }

  render() {
    const { selected } = this.state;
    const menu = Menu(list, selected);

    return (
      <div className="App">
        <ScrollMenu
          data={menu}
          arrowLeft={ArrowLeft}
          arrowRight={ArrowRight}
          selected={selected}
          onSelect={this.onSelect}
        />
      </div>
    );
  }
}

export default AppList;

Modified App.css

.menu-item {
  padding: 0 40px;
  margin: 1px 10px;
  user-select: none;
  cursor: pointer;
  border: 2px solid;
}

.menu-item-wrapper.active {
  border: 1px blue solid;
}

.menu-item.active {
  border: 1px green solid;
}

.scroll-menu-arrow {
  padding: 20px;
  cursor: pointer;
}

/* Remove default container padding */
.scroll-menu-container {
  padding-left: 0 !important;
  padding-right: 0 !important;
}

Why This Works:

  • Fixing the arrow components ensures they're rendered properly as React elements, avoiding layout glitches.
  • Correcting the selected prop logic ensures only the active item gets the active class, preventing unintended styling.
  • Generating menu items in the render method ensures the UI updates when the selected state changes.
  • Removing the container padding eliminates the extra space between the arrow and the first item.

内容的提问来源于stack exchange,提问作者Däñish Shärmä

火山引擎 最新活动