I've written a component that represents a select
with a set of options. Options are pulled from an object. The idea is that instead of 0, I want to display a cross (\u{274C}
), and I also want to be able to revert to an empty field. It's important to me that the empty field does not have an integer
value. I save an object with a key-value pair in localStorage and check what data ends up there. In general, I've found 2 problems that I don't quite understand how to solve: 1) When I choose 0, the cross is not displayed. 2) If I choose 0 and then try to return to an empty value, I see that 0 remains in localStorage. I don't need 0 there. Any ideas on what I'm missing?"
const SelectField: React.FC<SelectFieldProps> = ({diceOptions, onOptionChange, selectedOptions}) => {
return(
<div className={Style.container}>
{diceOptions.map((diceOption: DiceType, index: number) => {
return (
<select
key={`${diceOption.id}-${index}`}
className={Style.select}
onChange={(e) => {
const value = e.target.value === "" ? "" : Number(e.target.value);
onOptionChange(diceOption.id, value);
}}
value={selectedOptions[diceOption.id][0] || ""}
>
{diceOption.values.map((value: number | "", index: number) => {
return (
<option key={index} value={value === 0 ? "0" : value}>
{value === 0 ? "\u{274C}": value}
</option>
)
})}
</select>
)
})}
</div>
)
}
Options are pulled from an object.
const diceOptions: Array<DiceType> = [
{id: 'One', values: ['', 0, 1, 2, 3, 4, 5]},
{id: 'Two', values: ['', 0, 2, 4, 6, 8, 10]},
{id: 'Three', values: ['', 0, 3, 6, 9, 12, 15]},
{id: 'Four', values: ['', 0, 4, 8, 12, 16, 20]},
{id: 'Five', values: ['', 0, 5, 10, 15, 20, 25]},
{id: 'Six', values: ['', 0, 6, 12, 18, 24, 30]}
];
Types:
export type DiceType = {
id: string,
values: Values[];
}
export type SelectFieldProps = {
diceOptions: DiceType[];
onOptionChange: (id: string, value: number | '') => void;
selectedOptions: {[key: string]: (number | '')[]};
}
export type StateType = Record<string, (number | '')[]>;
export type ActionType = { type: 'clear' | 'replace', id?: string, value?: number | '' };
const App: React.FC = () => {
const [state, dispatch] = useReducer(optionReducer, initialState);
const handleSelectChange = (id: string, value: number | ''):void => {
dispatch({type: 'replace', id, value });
}
return (
<>
<SelectField diceOptions={diceOptions} onOptionChange={handleSelectChange} selectedOptions={state}/>
<button onClick={() => clearLocalStorage(dispatch)}>Clear storage</button>
</>
)
}
So the problem was with this line:
value={selectedOptions[diceOption.id][0] || ""}
Whenever my first element is null, undefined, 0, false
(and 0
is just my case) it shows an empty string.