Summary
A selectOne (or selectMultiple) field whose options include two entries with the same label (but different value) causes a rendering glitch: the duplicated option bleeds into other selectOne fields that are opened after it while paging through an observation's questions.
Originally reported against the config tooling in digidem/comapeocat#49, but the root cause is in this app.
Root cause
src/frontend/screens/ObservationFields/index.tsx pages between questions with navigation.popTo('ObservationFields', {question: n}) — the same route, so React Navigation keeps a single screen instance and re-renders <Question> with a different field.
Each field renders its options list keyed by item.label:
src/frontend/screens/ObservationFields/SelectOne.tsx (key={item.label})
src/frontend/screens/ObservationFields/SelectMultiple.tsx (key={item.label})
When a field has two options with the same label, the list has duplicate React keys. React can no longer cleanly reconcile the previous field's rendered children against the next field's, so a stale option element leaks into a field opened later — the glitch seen in comapeocat#49.
The config itself is valid (distinct values); the bug is purely client-side rendering.
Fix
Use a unique key (`${item.value}-${index}`) instead of item.label in both components. This is robust even if a malformed config duplicates both label and value, and index is a stable key here since field.options never reorders.
Note
Tracking adding validation errors to config files to avoid duplicate labels in the first place in digidem/comapeocat#49
Summary
A
selectOne(orselectMultiple) field whose options include two entries with the samelabel(but differentvalue) causes a rendering glitch: the duplicated option bleeds into otherselectOnefields that are opened after it while paging through an observation's questions.Originally reported against the config tooling in digidem/comapeocat#49, but the root cause is in this app.
Root cause
src/frontend/screens/ObservationFields/index.tsxpages between questions withnavigation.popTo('ObservationFields', {question: n})— the same route, so React Navigation keeps a single screen instance and re-renders<Question>with a differentfield.Each field renders its options list keyed by
item.label:src/frontend/screens/ObservationFields/SelectOne.tsx(key={item.label})src/frontend/screens/ObservationFields/SelectMultiple.tsx(key={item.label})When a field has two options with the same label, the list has duplicate React keys. React can no longer cleanly reconcile the previous field's rendered children against the next field's, so a stale option element leaks into a field opened later — the glitch seen in comapeocat#49.
The config itself is valid (distinct
values); the bug is purely client-side rendering.Fix
Use a unique key (
`${item.value}-${index}`) instead ofitem.labelin both components. This is robust even if a malformed config duplicates both label and value, andindexis a stable key here sincefield.optionsnever reorders.Note
Tracking adding validation errors to config files to avoid duplicate labels in the first place in digidem/comapeocat#49