#State mutation

7 messages · Page 1 of 1 (latest)

sweet bramble
#

I have a component that looked like this (stripped down version):

const cellEditor =  (props, editor_params) => {
    return (
            <input type={getInputType(editor_params.data_type)} onInput={(e) => props.low = e.target.value} value={props.low ?? ''} />
    )
}

that input, needs to show in a couple of different places so I extrapolated it to a component:

const CellInput : Component<{data_type: DataType, value: string}> = (props) => {
    const [value, setValue] = createSignal(props.value)
    const formattedValue = () => value() ?? "" 
    createEffect(() => {
        console.log('hi')
        props.value = value()
    })
    return (
        <input type={getInputType(props.data_type)}
               value={formattedValue()}
               onInput={(e) => {
                    e.preventDefault()
                    console.log('regex',data_regex(props.data_type))
                    if(e.target.value.match(data_regex(props.data_type))){
                        setValue(e.target.value)
                    }

               }}
        />
    )

when I changed the input in the original component to be CellInput like this:

  <CellInput data_type={editor_params.data_type} value={props.low}/>        

I get an error dev.js:969 Uncaught TypeError: Cannot set property value of #<Object> which has only a getter
how can I accomplish this?

maiden pewter
#

First, use currentTarget instead of target for onInput or onChange events (as an aside, unlike react, solid isn't swapping those both events).

#

But as for your problem: you try to overwrite props, which are read-only.

#

to set a reactive value in the parent, you need to provide a setter.

#

Though another route would be to put the onInput event in the parent and provide it as a prop.

sweet bramble
#

I wanted to wrap, to make it an inner concern and make it more clear.
I did what you sugessted now it look like this:

const CellInput : Component<{data_type: DataType, value: string, setValue: Function}> = (props) => {
    const formattedValue = () => props.value ?? "" 
    const regex = data_regex(props.data_type)
    return (
        <input type={getInputType(props.data_type)}
               value={formattedValue()}
               onInput={(e) => {
                    if(regex.test(e.currentTarget.value)){
                        props.setValue(e.currentTarget.value)
                    }

               }}
        />
    )
}

and it works, my question is, why was it treated as readOnly.
I'm learning while integrating ag-grid, and to call my outside cell editor it looks like this:

export const customCellEditor = (params: ICellEditorParams) => {
    const cell = params.data[params.column.getColId()];
    return cellEditor(cell,params.colDef.cellEditorParams);
}

so as you saw in the parent before the change, I changed a prop value without a problem, is that because it wasn't originated inside a solid component?

maiden pewter
#

yes, exactly.