Tcomb-form-native: Cannot dynamically hide/unhide a field

Created on 4 Sep 2018  路  6Comments  路  Source: gcanti/tcomb-form-native

Version

Tell us which versions you are using:

  • tcomb-form-native v0.6.15
  • react-native v0.55.4

Expected behaviour

Expect that I can dynamically change whether a field is hidden.

Actual behaviour

Changing the hidden property of the field options does not change the field visibility.

Steps to reproduce

  1. Add the options object to state and set the options property of
    to this.state.options.
        <Form 
          ref={c => this._form = c}
          templates={templates}
          type={this.state.struct} 
          options={this.state.options}
          value={this.state.data}
          onChange={this._handleChange}
        />
  1. Change the hidden property of a field in the options and update the state.
options.fields.myField.hidden = true
this.setState({ options })
  1. Field visibility does not change. From what I can tell, it is causing shouldComponentUpdate to fire (in Component class of tcomb-form-native/lib/component.js but nextProps.options and this.props.options are always the same, meaning they both have the value of hidden after step no. 2 (in this case, both show hidden = true). I would expect that this.props.options would have hidden = false for myField and nextProps.options would have hidden = true for myField. But because they are both the same, nextProps.options !== this.props.options returns false and won't force an update.

Stack trace and console log

All 6 comments

Researching a little further, it looks like a state change is invoking shouldComponentUpdate. The options prop updating is not. That would explain why nextProps.options === this.props.options. I'm only seeing it because a state change (at the same time the options are being updated to set the hidden property, during the screen load) is causing shouldComponentUpdate.

Because options={this.state.options} is changed on Form, which does not extend the local Component, shouldComponentUpdate is not invoked when this.state.options is updated. That explains the behavior. And from the way that Form uses Struct to create the form components, it does not appear there is a way to hide fields dynamically. Unless I'm missing something.

There's something new about this issue? I'm really having problems to use dynamic forms and keep default values.

Anyone can answer this ?

I'm also facing the same issue. Please help if anyone can?

Hi guys, i find an workaround hope this helps.

_handleFormChanges = values => {
        let opts
        if(values.interno){
            opts = t.update(this.state.options, {
                fields: {
                    legajo: {
                        hidden: {'$set': false}
                    }
                }
            })
        }else{
            opts = t.update(this.state.options, {
                fields: {
                    legajo: {
                        hidden: {'$set': true}
                    }
                }
            })
        }

        this.setState({options: opts, value: values})

    }

@ivanlynch solution doesn't work for me.
Has anybody found a solution? @tresheffron or @usmanuj7 or anybody else?

I also tried the supposed-to-be straightforward solution:

let newOptions = { ...this.state.options };
newOptions.fields.name.hidden = false;
this.setState({ options: newOptions });

Which didn't work either.

In both cases, I see that the hidden field is updated properly, and render is executed with the correct value. Still, it doesn't have an effect.

The initial setting of hidden does work.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

scarlac picture scarlac  路  4Comments

abdelghafourzguindou picture abdelghafourzguindou  路  4Comments

ilyadoroshin picture ilyadoroshin  路  4Comments

casoetan picture casoetan  路  5Comments

michaelbenker picture michaelbenker  路  3Comments