I implemented a ChipInput component which when focused will behave a string and onBlur will be transformed into a Chip component with the chips introduced by a comma. All works well except for a single issue. When I type in multiple words, and I want to add a new letter in between, the cursor takes me to the end but I want the cursor to stay at the same position.
Could someone please help me out? Thanks.
This is my Stackblitz link
CodePudding user response:
This issue occurs because the ChipInput
component is rerendered every time there is a change in the value of name
in index.tsx
.
One solution to this problem is to change the way state
inside ChipInput.tsx
is updated.
- Firstly, remove the following
useEffect
code fromChipInput.tsx
:
useEffect(() => {
setState({
inputValue: values,
value: compact(map(split(values, separator), (i) => trim(i))),
});
}, [values]);
- Change the initial value of
state
to:
const [state, setState] = useSetState<IChipInputState>({
value: compact(map(split(values, separator), (i) => trim(i))),
inputValue: values,
isFocused: false,
});
- Modify the
setState
statement thedeleteChip
function to:
setState({
value: newChipValues,
inputValue: join(newChipValues, `${separator} `),
isFocused: false,
});
The deleteChip
function would then look like:
const deleteChip = (chipValue: string): void => {
const newChipValues = without(state.value, chipValue);
setState({
value: newChipValues,
inputValue: join(newChipValues, `${separator} `),
isFocused: false,
});
onHandleChange(join(newChipValues, `${separator} `), name);
};
- Finally add
setState(prev => ({...prev, inputValue: onChangeValue }));
to the end of the onInputChange
prop of the Autocomplete
component in ChipInput.tsx
. The onInputChange
prop would then look like:
onInputChange={(event, newInputValue) => {
let onChangeValue = newInputValue;
if (acceptOnlyNumbers) {
onChangeValue = replace(newInputValue, /[^\d, ]/, '');
}
if (acceptOnlyNumbersPercentage) {
onChangeValue = replace(newInputValue, /[^\d,% ]/, '');
}
onHandleChange(onChangeValue, name);
setState(prev => ({...prev, inputValue: onChangeValue }));
}}