Building custom input component with expanding list causing issues
The issue you're experiencing is that you're mutating the props.schemaType.options object directly, which causes the list to accumulate on every render. In React, props should be treated as immutable, and schemaType is a shared object reference that persists across renders.
When you do:
props.schemaType.options = {...props.schemaType.options, list: [...list, ...myList]}You're modifying the actual schema type object, so each render adds to the already-modified list rather than the original one.
Solution
Create a new local options object instead of mutating the original. Here's how to fix it:
export function CustomStringInput(props: StringInputProps) {
// Create a new schemaType with expanded options without mutating the original
const expandedSchemaType = {
...props.schemaType,
options: {
...props.schemaType.options,
list: [...(props.schemaType.options?.list || []), ...myList]
}
}
// Pass the new schemaType to renderDefault
return props.renderDefault({
...props,
schemaType: expandedSchemaType
})
}Key Points
- Never mutate props directly - Always create new objects when you need to modify data
- Create the expanded options in the render - This ensures you start from the original schema definition each time
- Pass the modified props to renderDefault - The renderDefault function accepts props as an argument, so you can pass your modified version
This approach ensures that each render starts with the original props.schemaType.options.list from your schema definition, then adds your custom items on top, rather than continuously appending to an ever-growing list.
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.