Возможности перейти на функциональный компонент к сожалению нет.легаси-проект со старым реактом версии менее 16, "тронешь-развалится"?
import { useRef, useEffect, useState } from 'react';
export default function App() {
const [count, setCount] = useState(0);
const countRef = useRef();
countRef.current = count;
useEffect(() => {
const clickEvent = () => {
console.log(`CountRef: ${countRef.current}`);
};
document.addEventListener('click', clickEvent);
return () => {
document.removeEventListener('click', clickEvent);
};
}, [countRef]);
return (
<div>
<button onClick={() => setCount((n) => n + 1)}>Count: {count}</button>
</div>
);
}
useEffect(() => {
countRef.current = count;
}, [countRef, count]);
// пропсы
type MyCompProps = {
value: string;
...
};
// для компонента указывается тип - "функциональный компонент с пропсами MyCompProps"
// далее не нужно указывать тип для props и тип возвращаемого значения - TS выводит сам.
export const MyComp: React.FC<MyCompProps> = (props) => {
...
return (<div>{props.value}</div>);
};
в данный момент я не знаю redux или mobx.
import React, { useMemo } from "react";
import * as S from "./dots.style";
function makeData(dots, shift, width) {
const normShift = shift >= 0 ? shift : shift - dots.length * shift;
return dots.map((dot, index) => ({
key: dot,
isFirst: index === 0,
isLast: index === dots.length - 1,
left: ((normShift + index) % dots.length) * width
}));
}
export const Dots = ({ dots, shift }) => {
const data = useMemo(() => makeData(dots, shift, 25), [dots, shift]);
return (
<S.Container>
{data.map(({ key, left, children }) => (
<S.Dot key={key} left={left}>
{key}
</S.Dot>
))}
</S.Container>
);
};
<img src={getImage(el.id)} />
поместить в отдельный реактовский компонент, например, StorageImage. Далее возможны различные варианты в зависимости от того, что используется на проекте. Наиболее простой - useQuery - это обеспечит кэширование и обновление стейта из коробки, и все остальные детали, прям вот всё что нужно для данного кейса.