reactjs - React 同一组件的多个实例获得相同的状态

标签 reactjs state

我有一个 React 组件,我正在创建它的 2 个副本。但是,当其中 1 的状态更新时,它也会更新第二个。我不确定是什么原因造成的。

这是我的代码:

这是我使用 2 个组件的地方:

{this.state.selectedTab === 0 ?
    <Carousel
       size={1}
       cultureInfo={this.state.cultureInfo}
       collaboratorError={this.state.activeCollaborationError}
       getPinnedError={this.state.getPinnedUsersError}
       pinActionError={this.state.isPinnedServerError}
       user={this.state.activeCollaboratorContactsData}
       isPinnedTab={false}
       startDate={this.state.startDate}
       isMapped={this.state.isMapped}
       resetPosition={this.state.resetCollabCarousel}
       isVisible={this.state.selectedTab === 0 }
/>
:
<Carousel
  size={1}
  cultureInfo={this.state.cultureInfo}
  collaboratorError={this.state.activeCollaborationError}
  getPinnedError={this.state.getPinnedUsersError}
  pinActionError={this.state.isPinnedServerError}
  user={this.state.pinnedUsers}
  isPinnedTab={true}
  startDate={this.state.startDate}
  isMapped={this.state.isMapped}
  resetPosition={this.state.resetPinnedCarousel}
  isVisible={this.state.selectedTab === 1}
/>
}

这是轮播代码:
interface ICarouselProps {
 size: number;
 cultureInfo: CultureInfo;
 collaboratorError: Error.DataLayerError;
 getPinnedError: Error.DataLayerError;
 pinActionError: Error.DataLayerError;
 user: ActiveCollaboratorContact[];
 isPinnedTab: boolean;
 startDate: Date;
 isMapped: boolean;
 resetPosition: boolean;
 isVisible: boolean;
}

interface ICarouselState {
 position: number;
 width: number;
 isActiveNext: boolean;
 isActivePrev: boolean;
 isActive: number;
 }

 const numSlides = 2;
 const width = 100;
 const move = width / numSlides;
 const max = width - move;
 const min = -max;

 const numOfCards = 4;

 export default class Carousel extends BaseComponent<ICarouselProps,     

      ICarouselState> {
constructor() {
    super();
    this.resetState();
}

componentWillReceiveProps(newProps: ICarouselProps): void {
    if (newProps && newProps.resetPosition) {
        this.resetState();
    }
}

doRender(): React.ReactElement<{}> {
    let wrapperWidth: number;
    let widthStyle: string;
    wrapperWidth = (this.state as ICarouselState).width;

    const style:  React.CSSProperties = {
        WebkitTransform: "translateX(" + this.state.position + "%)",
        transform: "translateX(" + this.state.position + "%)",
        MozTransform: "translateX(" + this.state.position + "%)",
        msTransform: "translateX(" + this.state.position + "%)",
        OTransform: "translateX(" + this.state.position + "%)",
        width: wrapperWidth + "%"
    } as React.CSSProperties;
    const slideWidth:  React.CSSProperties = {width: move + "%"} as React.CSSProperties;
    let nextIsDisabled: boolean;
    let prevIsDisabled: boolean;
    let slideActive: string;

    widthStyle = (this.props.size === 0) ? styles.vCard : styles.hCard;
    nextIsDisabled = !this.state.isActiveNext;
    prevIsDisabled = !this.state.isActivePrev;
    slideActive = "slideActive" + this.state.isActive;

        const totalUsers = this.props.user.length;
        const articles: JSX.Element[] = [];


        for (let i = 0; i < 2; i++) {
            const cards: JSX.Element[] = [];
            for (let j = 0; j < numOfCards; j++) {
                const userIndex = i * numOfCards + j;
                if (userIndex < totalUsers) {
                    const card: JSX.Element = <Card
                        cultureInfo={this.props.cultureInfo}
                        user={this.props.user[userIndex]}
                        startDate={this.props.startDate}
                        extraMargin={userIndex % numOfCards === 0}
                    />;
                    cards.push(card);
                }
            }
            const article: JSX.Element =
                    <article className={styles.slideSingle}
                            tabIndex={0}
                            style={slideWidth}>
                        {cards}
                    </article>;
            articles.push(article);
        }
        return this.props.isVisible ?
                <div>
                    <div className={widthStyle + " " + styles.carousel + " " + slideActive} tabIndex={-1} id="Carousel">
                        <div className={styles.slideWrapper}
                            style={style}>
                            {articles}
                        </div>
                        <nav className={styles.nav}>
                            <ul className={styles.arrows}>
                                <li className={styles.stepLeft}>
                                <a disabled={prevIsDisabled} aria-disabled={prevIsDisabled} className={styles.previous} href="#"
                                    tabIndex={0}
                                    onClick = {this.prevSlideClicked}>
                                    BUTTONPREVTEXT
                                </a>
                                </li>
                                <li className={styles.stepRight}>
                                <a disabled={nextIsDisabled} aria-disabled={nextIsDisabled} className={styles.next} href="#"
                                    tabIndex={0}
                                    onClick = {this.nextSlideClicked}>BUTTONNEXTTEXT
                                </a>
                                </li>
                            </ul>
                        </nav>
                    </div>
               </div> :
               null;

};

private resetState(): void {
    const newState: ICarouselState = {
            position: 0,
            width: numSlides * 100,
            isActiveNext: true,
            isActivePrev: false,
            isActive: 0
        };

    if (this.state) {
        this.setState(newState);
    } else {
        this.state = newState;
    }
}

private nextSlideClicked: () => void = () => {
    if (this.state.position > min + move) {
        this.setState({
            position: this.state.position - move,
            width: numSlides * 100,
            isActiveNext: true,
            isActivePrev: true,
            isActive: Math.abs((this.state.position - move) / move)
        });
    } else if ((this.state as ICarouselState).position > min) {
        this.setState({
            position: this.state.position - move,
            width: numSlides * 100,
            isActiveNext: false,
            isActivePrev: true,
            isActive: Math.abs((this.state.position - move) / move)
        });
    }
};

private prevSlideClicked: () => void = () => {
    if (this.state.position < 0 - move) {
        this.setState({
            position: this.state.position + move,
            width: numSlides * 100,
            isActiveNext: true,
            isActivePrev: true,
            isActive: Math.abs((this.state.position + move) / move)
        });
    } else if (this.state.position < 0) {
        this.setState({
            position: this.state.position + move,
            width: numSlides * 100,
            isActiveNext: true,
            isActivePrev: false,
            isActive: Math.abs((this.state.position + move) / move)
        });
    }
};

private getCarouselName(): CarouselNames {
    return "name"
}

};

谢谢。

最佳答案

我有同样的问题。我在每个实例上设置了一个不同的“key”属性,问题就消失了。

关于reactjs - React 同一组件的多个实例获得相同的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38710250/

相关文章:

javascript - Redux 中的异步请求

reactjs - 当 onChange 被调用时,react-quill 失去焦点

javascript - 我无法进入嵌套 JSON 对象,但只是有时

C# Winforms : programatically display Button's Hover State

c# - Unity3D第三方C#库包含

java - 尝试保存 EditText 时无法暂停

javascript - React Js 上的条件 jsx

javascript - React.js - 在 Render 中区分加载/空状态的简洁方法

javascript - 如何只改变状态的一部分?

swift - 如何在 SwiftUI/Combine 中将订阅者附加到状态或绑定(bind)?