Consider the following. You are building a reusable item carousel. For that the requirements are that the slide track component and the slide navigation component have to be independent and in a sibling relationship so you can place the buttons where you like. How can I now trigger let’s say the moveForward function in the slide track component when I click the button in the slide navigation component?
I have a solution but it is not very elegant. Basically I store some state in the parent that changes if the button is clicked, and listen to that in the slide track via an effect.
In the parent:
export const ParentWithSlider: React.FC = () => {
const [moveForward, setMoveForward] = React.useState(false)
const [moveBackward, setMoveBackward] = React.useState(false)
return <section>
<ItemSliderButtons
setMoveBackward={setMoveBackward}
setMoveForward={setMoveForward}
/>
<ItemSlider
setMoveBackward={setMoveBackward}
setMoveForward={setMoveForward}
moveForward={moveForward}
moveBackward={moveBackward}
>
</section>
}
And then in the item slider component I do something like this
React.useEffect(() => {
if (props.moveForward) {
// calls the forward implementation in the item slider
triggerMyForwardFunc()
props.setMoveForward(false)
}
}, [props.moveForward])
I feel like there must be a better way. Keep in mind the item slider button component cannot be a child of the item slider component.
2
Answers
1) Create a function in the parent component that performs the desired action when the button is clicked.
In your case, this would be the moveForward function:
2) In the SlideNavigation component (ItemSliderButtons), accept the moveForward function as a prop and call it when the button is clicked:
3) Now, when the button in the SlideNavigation component is clicked, it will call the
moveForward
function defined in the parent component.The
ItemSlider
can expose the functions withuseImperativeHandler
:The parent assigns a
ref
toItemSlider
, and you can use the functions directly inItemSliderButtons
: