javascript React.正在重新呈现嵌套数组

jm81lzqq  于 2023-02-18  发布在  Java
关注(0)|答案(1)|浏览(129)

我正在建立测验应用程序,有一个问题,我必须 Shuffle 问题选项,但他们位于嵌套的问题数组。下面是界面:

export interface IConnectionsQuestionData extends IQuestionData {
    type: 'connections';
    questionsTitle: string;
    answersTitle: string;

    pairs: {
        questionOption: IConnectionsOption;
        answerOption: Maybe<IConnectionsOption>;
    }[];
} 

export interface IConnectionsOption {
    key: IDType;
    value: string;
    type: 'answer' | 'question'
}

因此,为了 Shuffle 选项,我创建了自定义useShuffle挂钩:

export const useShuffle = <T>(array: T[]): T[] => {
    return useMemo(() => {
        return shuffleArray(array);
    }, [array]) 
}

Question组件中,我从props中获取question。我使用这个钩子如下:

const shuffledLeftSideOptions = useShuffle(question?.pairs.map(pair => pair.questionOption) ?? [])
 const shuffledRightSideOptions = useShuffle(question?.pairs.map(pair => pair.answerOption) ?? [])

但每次组件需要重新渲染时,我选择选项,选项数组 Shuffle 再次对每一个渲染。我试图测试它,它的工作与pairs阵列,但与questionanswer选项 Shuffle 。

2izufjch

2izufjch1#

你只记住了shuffling,而没有记住map操作,所以你每次都得到一个新的数组,因为map每次都产生一个新的数组,所以useShuffle每次都要做它的工作。
如果您需要执行map,您还需要记住它,例如:

const mappedLeftOptions = useMemo(
    () => question?.pairs.map((pair) => pair.questionOption) ?? [],
    [question]
);
const mappedRightOptions = useMemo(
    () => question?.pairs.map((pair) => pair.answerOption) ?? [],
    [question]
);
const shuffledLeftSideOptions = useShuffle(mappedLeftOptions);
const shuffledRightSideOptions = useShuffle(mappedRightOptions);

但是,请注意,useMemo提供的记忆化仅提供性能优化,而不是语义保证。(更多信息请参见the documentation。)但是您的shuffling代码依赖于它,就好像它是语义保证一样。

相反,当您需要语义保证时,请使用ref:

export const useShuffle = <T>(array: T[]): T[] => {
    const arrayRef = useRef<T[] | null>(null);
    const shuffleRef = useRef<T[] | null>(null);
    if (!Object.is(array, arrayRef.current)) {
        shuffleRef.current = null;
    }
    if (!shuffleRef.current) {
        arrayRef.current = array;
        shuffleRef.current = shuffleArray(array);
    }
    return shuffleRef.current;
};

或者它可能更干净,只有一个参考:

export const useShuffle = <T>(array: T[]): T[] => {
    const ref = useRef<{ array: T[]; shuffled: T[] } | null>(null);
    if (!ref.current || !Object.is(ref.current.array, array)) {
        ref.current = {
            array,
            shuffled: shuffleArray(array),
        };
    }
    return ref.current.shuffled;
};

相关问题