1

长期以来,我一直在为看似简单的解决方案而苦苦挣扎。我是打字稿的新手,也是反应新手。

我正在尝试使用 react-muli-carousel NPM 包。

我能够让 customButtonGroup 在沙箱中成功工作: https ://codesandbox.io/s/fervent-rain-332mn?file=/src/App.js:834-913

但是当我尝试在我的 SPFX 解决方案中实现它时,我收到以下错误:

Type '{}' is missing the following properties from type '{ [x: string]: any; next: any; previous: any; goToSlide: any; }': next, previous, goToSlide

import * as React from 'react';
import { IBrandsCarouselProps } from './IBrandsCarouselProps';
import { IBrandsCarouselState } from './IBrandsCarouselState';
import { IBrand } from './IBrand';
import styles from '../../../styles/styles.module.scss';
import { SPHttpClient } from '@microsoft/sp-http';
import Carousel from 'react-multi-carousel';
import 'react-multi-carousel/lib/styles.css';
import '../../../styles/react-carousel.scss';
import { getNextElement } from 'office-ui-fabric-react';


const responsive = {
    desktop: {
        breakpoint: { max: 4000, min: 768 },
        items: 4,
        partialVisibilityGutter: 0
    },
    tablet: {
        breakpoint: { max: 768, min: 480 },
        items: 3,
        partialVisibilityGutter: 30
    },
    mobile: {
        breakpoint: { max: 480, min: 0 },
        items: 2,
        partialVisibilityGutter: 30
    }
};



export default class BrandsCarousel extends React.Component<IBrandsCarouselProps, IBrandsCarouselState>{


    constructor(props) {
        super(props);

        this.state = {
            displayedBrands: [],
            isLoading: true
        };
    }

    /**
   * Loads data from a list by using a cached view
   */
    public loadBrandsFromList(): Promise<IBrand[]> {

        const queryUrlGetAllItems: string = `[[HIDDEN]]`;


        return this.props.context.spHttpClient.get(
            queryUrlGetAllItems,
            SPHttpClient.configurations.v1)
            .then(
                (response: any) => {
                    if (response.status >= 200 && response.status < 300) {
                        return response.json();
                    } else {
                        return Promise.resolve(new Error(JSON.stringify(response)));
                    }
                })
            .then((data: any) => {
                let documents: IBrand[] = [];
                if (data) {
                    for (let i = 0; i < data.value.length; i++) {
                        let item = data.value[i];
                        var doc: IBrand = {
                            Title: item.Title,
                            Image: item.Image.Url ? item.Image.Url : "No Image Set",
                            Url: item.Url.Url,
                            Business: item.Business
                        };
                        documents.push(doc);
                    }
                }
                return documents;

            }).catch((ex) => {
                // console.log("readDocumentsFromLibrary > spHttpClient.get()...catch:", ex);
                throw ex;
            });

    }


    public render(): React.ReactElement<IBrandsCarouselProps> {


        // Sorting is Done in the Rest Call
        let items = this.state.displayedBrands;

        // create a new list that filters by the tags
        // Business is an array of strings
        // If the item has an array value that matches the Props Business

        if (this.props.Business != "All") {
            let filteredItems = [];

            for (let i = 0; i < items.length; i++) {
                const item = items[i];
                if (item.Business.indexOf(this.props.Business) > -1) {
                    filteredItems.push(item);
                }
            }

            items = filteredItems;
        }

        const ButtonGroup = ({ next, previous, goToSlide, ...rest }) => {
            const {
                carouselState: { currentSlide }
            } = rest;
            return (
                <div className="carousel-button-group">
                    <div
                        className={currentSlide === 0 ? "disable" : ""}
                        onClick={() => previous()}
                    >
                        Prev
                        </div>
                    <div onClick={() => next()}>Next</div>
                    <div onClick={() => goToSlide(currentSlide + 1)}> Go to any slide </div>

                </div>
            );
        };

        return (

            <div className={styles["brands-slider"] + " " + styles["card-docs-slider"] + " hub-carousel"}>
                {this.props.IsTitle && this.props.Title != "" &&
                    <div className={styles["widget-header"]}>
                        <span className={styles["view"]}>{this.props.Title}</span>
                    </div>
                }
                <div className={styles["card-slider"]}>
                    {items && items.length > 0 &&
                        <Carousel
                            responsive={responsive}
                            arrows
                            additionalTransfrom={0}
                            itemClass={"react-carousel-item"}
                            minimumTouchDrag={80}
                            partialVisible
                            renderButtonGroupOutside
                            customButtonGroup={<ButtonGroup />}
                        >
                            {items.map((item) => {
                                return (
                                    <a href={item.Url} className={styles["block-link"]} target="_blank">
                                        <img src={item.Image} alt={item.Title} />
                                    </a>
                                );
                            })
                            }
                        </Carousel>
                    }
                    {items && items.length == 0 &&
                        <p>No Brands found. Please, check the List</p>
                    }
                </div>
            </div>


        );
    }

    public componentDidMount() {
        this.loadBrandsFromList().then(
            //resolve
            (documents: IBrand[]) => {
                this.setState({
                    displayedBrands: documents,
                    isLoading: false,
                });
            },
            //reject
            (data: any) => {
                this.setState({
                    displayedBrands: [],
                    isLoading: false,
                    isErrorOccured: true,
                    errorMessage: data
                });
            }
        ).catch((ex) => {
            this.setState({
                displayedBrands: [],
                isLoading: false,
                isErrorOccured: true,
                errorMessage: ex.errorMessage
            });

        });
    }
}

任何帮助将不胜感激。谢谢!

4

1 回答 1

3

我能够弄清楚。我需要传递参数。哎呀!

希望这可以帮助将来的另一个 JSX、Typescript、React 初学者。

                        <Carousel
                            responsive={responsive}
                            arrows
                            additionalTransfrom={0}
                            itemClass={"react-carousel-item"}
                            minimumTouchDrag={80}
                            partialVisible
                            renderButtonGroupOutside
                            customButtonGroup={<ButtonGroup
                                next={this.props.next}
                                previous={this.props.previous}
                                rest={this.props.rest}
                            />}
                        >

如果它也有帮助,这里是自定义按钮组。我找不到隐藏下一个按钮的文档。

const ButtonGroup = ({ next, previous, ...rest }) => {
            const {
                carouselState: { currentSlide, totalItems, slidesToShow }
            } = rest;

            return (
                <div className="carousel-button-group">
                    <button aria-label="Go to previous slide"
                        className={currentSlide === 0 ? "disable" : "react-multiple-carousel__arrow react-multiple-carousel__arrow--left"}
                        onClick={() => previous()}></button>
                    <button aria-label="Go to next slide" 
                        className={currentSlide === totalItems - slidesToShow ? "disable" : "react-multiple-carousel__arrow react-multiple-carousel__arrow--right"}
                        onClick={() => next()}></button>
                </div>
            );
        };
于 2020-05-01T15:52:30.073 回答