Skip to content

Commit

Permalink
perf: useQuestions -> `useQuestionEls
Browse files Browse the repository at this point in the history
  • Loading branch information
JianJroh committed Jun 6, 2023
1 parent 4072c24 commit 18e8d67
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 22 deletions.
10 changes: 3 additions & 7 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
import { useMemo, useState } from 'react';
import { queryQuestionEls } from './helpers';
import { useQuestions } from './hooks/useQuestions';
import { useQuestionEls } from './hooks/useQuestionEls';
import { useActiveQuestionIndex } from './hooks/useActiveQuestionIndex';
import { useHovering } from './hooks/common/useHovering';
import { useMountedCallbackValue } from './hooks/common/useMountedCallbackValue';

function App() {
const questions = useQuestions();
const { questions, questionEls } = useQuestionEls();
const activeQuestionIndex = useActiveQuestionIndex();
const [elRef, hovering] = useHovering<HTMLUListElement>();
const [open, setOpen] = useState(true);
const show = useMemo(() => open || hovering, [hovering, open]);

const questionEls = useMountedCallbackValue(queryQuestionEls);

const handleClickList: React.MouseEventHandler<HTMLUListElement> = (event) => {
if (event.target instanceof HTMLLIElement) {
const targetIndex = Number(event.target.dataset.index);
questionEls.current?.[targetIndex]?.scrollIntoView({ behavior: 'smooth' });
questionEls?.[targetIndex]?.scrollIntoView({ behavior: 'smooth' });
}
};

Expand Down
4 changes: 0 additions & 4 deletions src/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ export function queryQuestionEls() {
}, []);
}

export function getQuestions() {
return queryQuestionEls().map((q) => q.innerText.trim() ?? '');
}

export function className2Selector(className: string) {
return className
.split(' ')
Expand Down
8 changes: 5 additions & 3 deletions src/hooks/common/useMountedCallbackValue.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { useEffect, useRef } from 'react';
import { useCallback, useEffect, useRef } from 'react';

export function useMountedCallbackValue<T>(cb: () => T) {
const value = useRef<T>();

const callback = useCallback(cb, [cb]);

useEffect(() => {
value.current = cb();
});
value.current = callback();
}, [callback]);

return value;
}
4 changes: 2 additions & 2 deletions src/hooks/useActiveQuestionIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import { queryChatContainer, queryQuestionEls } from '../helpers';
import { useEventListener } from './common/useEventListener';
import { useMountedCallbackValue } from './common/useMountedCallbackValue';
import { isSharePage, scrollMarginTop } from '../helpers/sharePage';
import { useQuestionEls } from './useQuestionEls';

const topThreshold = isSharePage ? scrollMarginTop : 0;

export function useActiveQuestionIndex() {
const [activeIndex, setActiveIndex] = useState<number | null>(null);

const { questionEls } = useQuestionEls();
const scrollContainer = useMountedCallbackValue(() => queryChatContainer()?.parentElement);

const findActiveIndex = () => {
const questionEls = queryQuestionEls();
const index = questionEls.findIndex((el) => el.getBoundingClientRect().top >= topThreshold);
if (index > -1) {
setActiveIndex(index);
Expand Down
14 changes: 8 additions & 6 deletions src/hooks/useQuestions.ts → src/hooks/useQuestionEls.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { useState } from 'react';
import { useMemo, useState } from 'react';
import { useMutationObserver } from './common/useMuationObserver';
import { getQuestions, queryChatContainer } from '../helpers';
import { queryChatContainer, queryQuestionEls } from '../helpers';
import { useMountedCallbackValue } from './common/useMountedCallbackValue';

export function useQuestions() {
const [questions, setQuestions] = useState(getQuestions());
export function useQuestionEls() {
const [questionEls, setQuestionEls] = useState(queryQuestionEls());

const questions = useMemo(() => questionEls.map((q) => q.innerText.trim() ?? ''), [questionEls]);

const chatContainer = useMountedCallbackValue(queryChatContainer);

Expand All @@ -13,7 +15,7 @@ export function useQuestions() {
(mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.type === 'childList') {
setQuestions(getQuestions());
setQuestionEls(queryQuestionEls());
}
}
},
Expand All @@ -22,5 +24,5 @@ export function useQuestions() {
}
);

return questions;
return { questionEls, questions };
}

0 comments on commit 18e8d67

Please sign in to comment.