Input onChange handler works on desktop but doesn't on iOS

Viewed 89

I have an input element where client starts typing an item name and it performs a search on backend over API. I get a list of results and client choses the item he wants.

In desktop browser my code works perfectly and I get my dropdown list of items, but when I tested it on iPhone I see no results, only the loader.

I prefer defining states and values in objects, like so:

interface IItem { ... }
type List = IItem[]

interface IState {
    typing: boolean;
    loading: boolean;
    open: boolean;
    timeout: ReturnType<typeof setTimeout>;
    // ...
}

interface IValue {
    item: IItem;
    list: List;
    // ...
}

const [state, setState] = React.useState<IState>({
    typing: false,
    loading: false,
    open: false,
    timeout: null,
    // ...
});

const [value, setValue] = React.useState<IValue>({
    item: { ... },
    list: [],
    // ...
});

This is my handler. Basically what it does it sets a timeout for 500ms to prevent calling API immediately user types a character and let him finish typing his query.

const handleChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
    if (state.timeout) {
        clearTimeout(state.timeout);
    }
    setState({
        ...state,
        typing: true,
        timeout: setTimeout(async () => {
            setValue({
                ...value,
                list: await searchItem(event.target.value),
            });
            setState({ ...state, typing: false });
        }, 500),
    });
};

const searchItem = async (query: string) => {
    setState({ ...state, loading: true });
    const result = await fetch("my-api-endpoint");
    const list: List = await result.json();
    setState({ ...state, loading: false });
    
    return list;
};

For styling I use Material-UI, this is another handler for Autocomplete component:

const handleSelect = (
    _event: React.MouseEvent<HTMLElement> | React.TouchEvent<HTMLElement>,
    selected: IItem
) => {
    setValue({
        ...value,
        item: selected ?? { /* default values */ },
    });
};

And finally this how my MUI component looks like:

<Autocomplete
    value={value.item}
    onChange={handleSelect}
    open={state.open}
    onOpen={() => setState({ ...state, open: true })}
    onClose={() => setState({ ...state, open: false })}
    getOptionSelected={(option, value) => option?.symbol === value?.symbol }
    options={value.list}
    loading={state.loading}
    renderInput={(params) => (
        <TextField
            {...params}
            onChange={handleChange}
        />
    )}
/>

As I mentioned at the beginning, my code works as expected on desktop, the problem is with iOS (didn't test Android). What am I missing?

0 Answers
Related