I've built a draggable slider component inside one of my pages, which changes the state of the info on a form as the tab is dragged further along the screen (horizontal only) but as the position changes and I set state in order to change the info on this form, it causes my page to re-render and as I am using useRef, it causes the page to re-render and useRef to be reset back to its original value.
How can I set the state so that the info on this form changes without re-rendering? so no matter if the user drags the tab left or right on the slider, it will render the correct info on the form and not reset the useRef once state is set.
This is an image of the slider to give you an idea, (the white tab is the draggable part)
And here is my code:
const FinancialLandingPage = () => {
const { t } = useTranslation();
const [selectedPlanDetails, setSelectedPlanDetails] = useState(SUBSCRIPTION_PLANS.newbie.name);
const DraggableComponent = () => {
const [pressed, setPressed] = useState(false);
const [position, setPosition] = useState({ x: 0, y: 0 });
const [currentPlan, setCurrentPlan] = useState(1);
const ref = useRef();
// Monitor changes to position state and update DOM
useEffect(() => {
if (ref.current) {
ref.current.style.transform = `translate(${position.x}px`;
}
if (position.x > 0 && position.x < 147) {
setCurrentPlan(1);
setSelectedPlanDetails(SUBSCRIPTION_PLANS.newbie.name);
} else if (position.x > 147 && position.x < 294) {
setCurrentPlan(2);
setSelectedPlanDetails(SUBSCRIPTION_PLANS.enthusiast.name);
} else if (position.x > 294 && position.x < 441) {
setCurrentPlan(3);
setSelectedPlanDetails(SUBSCRIPTION_PLANS.trader.name);
} else if (position.x > 441 && position.x < 600) {
setCurrentPlan(4);
setSelectedPlanDetails(SUBSCRIPTION_PLANS.traderplus.name);
}
}, [position]);
// Update the current position if mouse is down
const onMouseMove = useCallback(
(event) => {
if (pressed) {
if (position.x + event.movementX < 0) {
setPosition({
x: 0,
y: position.y + 0,
});
return;
}
if (position.x + event.movementX >= 600) {
setPosition({
x: 610,
y: position.y + 0,
});
return;
}
setPosition({
x: position.x + event.movementX,
y: position.y + 0,
});
}
},
[pressed, position]
);
return (
<div
ref={ref}
onMouseMove={onMouseMove}
onMouseDown={() => setPressed(true)}
onMouseUp={() => setPressed(false)}
>
<div className="slider-bar-item">
<Heading level={"5"}>{t(base_t + "page_five.slider").replace("[num]", currentPlan)}</Heading>
</div>
</div>
);
};
return (
<>
<div className={"slider"}>
<div className="slider-bar">
<DraggableComponent />
</div>
</div>
<div className={"form-container"}>
<div className={"header"}>
<Heading align={"center"} level={"3"}>
{t(base_t + "page_five.form.title")}
</Heading>
<Heading align={"center"} level={"1"}>
{t(base_t +
`page_five.form.${selectedPlanDetails}.price`)}
</Heading>
<Heading align={"center"} level={"6"}>
{t(base_t + "page_five.form.price_description")}
</Heading>
</div>
<div className={"form"}>
<div className={"form-item"}>
<CryptoIcon name={"checkmark"} />
<Text size={16}>
{t(base_t +
`page_five.form.${selectedPlanDetails}.item_one`)}
</Text>
</div>
<div className={"form-item"}>
<CryptoIcon name={"checkmark"} />
<Text size={16}>
{t(base_t +
`page_five.form.${selectedPlanDetails}.item_two`)}
</Text>
</div>
<div className={"form-item"}>
<CryptoIcon name={"checkmark"} />
<Text size={16}>
{__(base_t +
`page_five.form.${selectedPlanDetails}.item_three`)}
</Text>
</div>
<Button className={"button"}>
{t(base_t + "page_five.form.button")}
<Icon name={"chevron_right"} />
</Button>
</div>
</div>
</>
);
export default FinancialLandingPage;
Thanks in advance!