tcomb-form-native icon indicating copy to clipboard operation
tcomb-form-native copied to clipboard

Dynamic form type calling onChange with empty values

Open sdg9 opened this issue 8 years ago • 1 comments

First off thanks for the awesome from library. I'm using one set of enums to display two pickers and duplicates are not allowed. Say the enum contains three items, choosing item 1 in the first picker will cause only item 2 and 3 to be available in the second picker.

I dynamically update the form type based on your suggestion in issue #97 the only problem is every interaction with the picker calls onChange twice. The first call to onChange is when I interact with the picker which sets the value and new form type to state. The second call to onChange is a reaction to form type updating and in doing so it passes an empty value to state for the other picker essentially resetting it back to an unselected state.

Do you have any tips on how to retain selection while dynamically re-populating the enums driving the picker? Ideally I don't want the second call to onChange or I want to pass the new form type the current form value to use when it calls onChange the second time.

Here is the code recreating this scenario

import React, {Component} from 'react';
import { View } from 'react-native';

import t from 'tcomb-form-native';
const Form = t.form.Form;

const items = {
  1: 'item 1',
  2: 'item 2',
  3: 'item 3',
};

// enforce uniqueness between pickers
const filterOutAlreadySelected = (value) => {
  if (value) {
    let valToUse = { ...items };
    delete valToUse[value];
    return t.enums(valToUse);
  }
  return t.enums(items);
};

const getType = (value) => {
  return t.struct({
    from: filterOutAlreadySelected(value.to),
    to: filterOutAlreadySelected(value.from)
  });
};

export default class TestFormScreen extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: {},
      type: getType({}),
    };
  }

  render() {
    return (
      <View>
        <Form
          ref="form"
          type={this.state.type}
          value={this.state.value}
          onChange={this.onChange.bind(this)} />
      </View>
    );
  }

  onChange(value) {
    this.setState({
      value,
      type: getType(value)
    });
  }
}

sdg9 avatar Sep 06 '16 14:09 sdg9

When using onChange = {this.onChange.bind (this)} nothing happens .. I am lost

luan-nvg avatar Apr 02 '20 05:04 luan-nvg