skip to Main Content

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. 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:

    export const ParentWithSlider: React.FC = () => {
      const moveForward = () => {
        // Logic to move the slider forward
      };
    
      return (
        <section>
          <ItemSliderButtons moveForward={moveForward} />
          <ItemSlider />
        </section>
      );
    }
    

    2) In the SlideNavigation component (ItemSliderButtons), accept the moveForward function as a prop and call it when the button is clicked:

    interface ItemSliderButtonsProps {
      moveForward: () => void;
    }
    
    const ItemSliderButtons: React.FC<ItemSliderButtonsProps> = ({ moveForward }) => {
      return (
        <div>
          {/* Button that triggers the moveForward function */}
          <button onClick={moveForward}>Move Forward</button>
        </div>
      );
    }
    

    3) Now, when the button in the SlideNavigation component is clicked, it will call the moveForward function defined in the parent component.

    Login or Signup to reply.
  2. The ItemSlider can expose the functions with useImperativeHandler:

    const ItemSlider = forwardRef((props, ref) {
      const forward = () => /* forward logic */;
      
      const backward = () => /* backward logic */;
    
      useImperativeHandle(ref, () => ({
        forward,
        backward,
      }), [])
      ...
    })
    

    The parent assigns a ref to ItemSlider, and you can use the functions directly in ItemSliderButtons:

    export const ParentWithSlider: React.FC = () => {
      const ref = useRef();
    
     return <section>
      <ItemSliderButtons
        backward={() => ref.current?.backward()}
        forward={() => ref.current?.forward()}
      />
      <ItemSlider ref={ref}>
     </section>
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search