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

React TypeScript项目中Nuka-Carousel getControlsContainerStyles属性报错

问题

在React TypeScript项目中使用Nuka-Carousel v4.8.4,基础实现完成后想要调整控制容器位置(将导航点移至轮播上方并修改文本)。根据官方文档尝试使用getControlsContainerStyles函数修改控制容器CSS属性,但触发类型错误:

getControlsContainerStyles does not exist on type intrinsicAttributes & Pick <partial<internalcarouselprops....

当前组件代码如下:

import React, { useState, useEffect } from 'react';
import { ICompetition } from '../interfaces/ICompetition';
import { IEvent } from '../interfaces/IEvent';
import "../App.css";
import { IMarket } from '../interfaces/IMarket';
import Market from './Market';
import Carousel, { PagingDots } from 'nuka-carousel';

interface CompetitionProps {
    competition: ICompetition;
    marketTypeFilter: string;
    competitionMeetingIdSetter: (arg0: string) => void;
}


function Competition(props: CompetitionProps) {
    const { competition, marketTypeFilter, competitionMeetingIdSetter } = props;
    const [meetingId, setMeetingId] = useState("");
    const query = new URLSearchParams(window.location.search)
    var mid = (query.has('mid') ? query.get('mid') : '');

    useEffect(() => {
        competitionMeetingIdSetter(meetingId);
    }, [competitionMeetingIdSetter, meetingId]);

    return (
        <div id="carouselIndicators">            
            {competition.sportId == 19 || meetingId !== "" ?
                (
                    <Carousel disableEdgeSwiping={true} autoplay={false} adaptiveHeight={true} renderCenterRightControls={null}
                        renderCenterLeftControls={null} renderBottomCenterControls={null} renderTopCenterControls={({ }) => (
                            <div>{competition.venue}</div>
                        )}
                        defaultControlsConfig={{
                            pagingDotsStyle: {
                                fill: 'red',
                                position: 'absolute',
                                top: '1px'
                            }
                            
                        }}                        
                        getControlsContainerStyles={(key) => {
                            switch (key) {
                                case 'TopLeft':
                                    return {
                                        backgroundColor: "red",
                                    };
                                default:
                                    // will apply all other keys
                                    return {
                                        backgroundColor: "blue",
                                    };
                            }
                        }}>
                            {competition.events && competition.events instanceof Array && competition.events?.map((event: IEvent) => (
                                <Market markets={event.markets} marketTypeFilter={marketTypeFilter} />
                            ))}
                    </Carousel>
                )
                :
                (
                    <div id="runnerContainer">
                        <div className="container">
                            <div className="row">
                                <div className="col-12">
                                    <div id={competition.competitionId.toString()} className="text-left" style={{ minWidth: 0, textOverflow: 'ellipsis', overflow: 'hidden' }}>
                                        <a id="lnkDisplay" style={{ justifyContent: 'left', fontWeight: 'bold' }} onClick={() => setMeetingId(competition.competitionId.toString())}>
                                            <span id="lblcompText" className="headerFontColour" >{competition.venue}</span>
                                        </a>
                                    </div>
                                </div>
                            </div>
                            <div className="row">
                                <div className="col-12">
                                    {competition.events && competition.events instanceof Array && competition.events?.map((event: IEvent) => (
                                        <button type="button" className="button button-primary raceButton" key={event.eventId} onClick={() => setMeetingId(competition.competitionId.toString())} >
                                            {new Date(event.startTime).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
                                        </button>
                                    ))}
                                </div>
                            </div>
                        </div>
                    </div>
                )
            }
        </div>
    );
}

export default Competition;

解决方案

1. 修正参数放置位置

getControlsContainerStyles并非Carousel组件的顶层props,它需要嵌套在defaultControlsConfig对象内部使用。修改代码如下:

<Carousel 
  disableEdgeSwiping={true} 
  autoplay={false} 
  adaptiveHeight={true} 
  renderCenterRightControls={null}
  renderCenterLeftControls={null} 
  renderBottomCenterControls={null} 
  renderTopCenterControls={({ }) => (
    <div>{competition.venue}</div>
  )}
  defaultControlsConfig={{
    pagingDotsStyle: {
      fill: 'red',
      position: 'absolute',
      top: '1px'
    },
    // 将getControlsContainerStyles移至此处
    getControlsContainerStyles={(key) => {
      switch (key) {
          case 'TopLeft':
              return { backgroundColor: "red" };
          default:
              return { backgroundColor: "blue" };
      }
    }}
  }}>
  {competition.events && competition.events instanceof Array && competition.events?.map((event: IEvent) => (
    <Market markets={event.markets} marketTypeFilter={marketTypeFilter} />
  ))}
</Carousel>

2. 处理类型定义兼容问题

如果调整位置后仍报错,大概率是v4.8.4的TypeScript类型定义未包含该属性,可通过以下方式解决:

  • 跳过类型检查:使用// @ts-ignore注释跳过单个属性的类型校验:
<Carousel 
  // 其他props
  // @ts-ignore
  getControlsContainerStyles={(key) => {
    // 样式逻辑
  }}
>
  • 升级依赖版本:将Nuka-Carousel升级到更高版本,新版本的类型定义可能已修复该问题。
  • 扩展自定义类型:创建扩展类型补充该属性定义:
import { CarouselProps } from 'nuka-carousel';

interface CustomCarouselProps extends CarouselProps {
  getControlsContainerStyles?: (key: string) => React.CSSProperties;
}

// 使用时
<Carousel {...props} as CustomCarouselProps
  getControlsContainerStyles={(key) => {
    // 样式逻辑
  }}
>

3. 替代方案:自定义导航组件

若上述方法均不生效,可放弃使用getControlsContainerStyles,通过renderTopCenterControls完全自定义导航容器与样式:

<Carousel 
  // 其他props
  renderTopCenterControls={({ currentSlide, slideCount, goToSlide }) => (
    <div style={{ 
      position: 'absolute', 
      top: '10px', 
      left: '50%', 
      transform: 'translateX(-50%)',
      display: 'flex',
      alignItems: 'center',
      gap: '8px'
    }}>
      {/* 自定义导航点 */}
      {Array.from({ length: slideCount }).map((_, index) => (
        <button 
          key={index}
          style={{ 
            width: '12px', 
            height: '12px', 
            borderRadius: '50%', 
            border: 'none',
            cursor: 'pointer',
            backgroundColor: index === currentSlide ? 'red' : '#ccc'
          }}
          onClick={() => goToSlide(index)}
        />
      ))}
      {/* 自定义文本 */}
      <span style={{ color: '#fff', fontSize: '14px' }}>{competition.venue}</span>
    </div>
  )}
>
  {/* 轮播内容 */}
</Carousel>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 20:17:54