segmented-control icon indicating copy to clipboard operation
segmented-control copied to clipboard

Does not behave as a controlled component on iOS

Open madox2 opened this issue 2 years ago • 1 comments

I am trying to use segmented control as a controlled component through selectedIndex and onChange properties. On iOS it does not work as expected. In the simple example below I want to execute special logic when clicking 'More' item, but it is ignoring the value prop and keeps selecting 'More' item.

export function Navigation() {
  const [value, onChange] = useState(0);
  return (
    <SegmentedControl
      values={['One', 'Two', 'More']}
      selectedIndex={value}
      onChange={event => {
        const { selectedSegmentIndex } = event.nativeEvent;
        if (selectedSegmentIndex > 1) {
          // onChange(value); // does not work either
          return;
        }
        onChange(selectedSegmentIndex);
      }}
    />
  );
}

On Android it works as expected. Version: "@react-native-segmented-control/segmented-control": "^2.4.2"

madox2 avatar Jul 11 '23 15:07 madox2

Hi there, Just had a similar issue in our codebase where we wanted to prevent/revert the switching to a tab in onChange. I adjusted our implementation for your useCase. It won't prevent setting more as the active element (as that's done natively on iOS), but it'll immediately update it to the segment index you provide:

export default function Navigation() {
  const [value, onChange] = useState(0);

  return (
    <SegmentedControl
      values={['One', 'Two', 'More']}
      selectedIndex={value}
      onChange={({nativeEvent}) => {       
        // align our state with the internal state of the segmented control
        onChange(nativeEvent.selectedSegmentIndex);
        
        if (nativeEvent.selectedSegmentIndex > 1) {
          // when 'more' is active, set it back to 'Two"
          InteractionManager.runAfterInteractions(() => {
            onChange(1);
          });
        }
      }}
    />
  );
}

If you want it to revert to the tab that was initially selected, I'd keep hold of that tab in a ref.

VNDRN avatar Nov 14 '24 14:11 VNDRN