The problem is as follows: Im using Material UI Autocomplete Component (https://material-ui.com/api/autocomplete/) in a Redux-Form. The Autocomplete Component is provided with a list of options where each option is an object, containing "@id" property, and some other human-readable properties, depending on the resource.
The component is told via "getOptionLabel" prop to generate options labels from the readable properties. After typing/selecting any label from the list provided by Autocomplete, the label is converted to input value, and thus stored in the store as value of the redux-form field.
Problem: Autocomplete component should provide redux-form with value different than the one present on label. However as of yet I'm unable to do it in some simple way. I'm sure its possible, but at this point I'm also sure that I don't understand which combination of component props would handle such scenario.
What I managed to do so far is using ChildContextTypes on the form itself, to pass the redux-form change dispatch (https://redux-form.com/8.2.2/docs/api/actioncreators.md/#-code-change-form-string-field-string-value-any-code-) to the Autocomplete component. This way, i can specify in the Autocomplete component an onChange event, that will handle switching the values.
Current code:
export class AutocompleteField extends React.Component {
constructor(props, context) {
super(props);
this.state = {
options: [],
selectedValue: null,
};
}
static contextTypes = {
changeFieldValue: PropTypes.func.isRequired
};
componentDidMount() {
this.fetchLabels();
}
fetchLabels() {
// call api, setState({options: resulst of api call })
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (!this.state.selectedValue) {
return;
}
this.context.changeFieldValue(`example_field`, `${this.state.selectedValue["@id"]}`);
}
changeLabelToIRI(event, value) {
this.setState({selectedValue: value})
}
getOptionsLabels(option) {
// format option labels according to resource
}
render() {
const {input} = this.props;
return(
<Autocomplete
options={this.state.options}
getOptionLabel={option => (this.getOptionLabels(option))}
onChange={(event, value ) => this.changeLabelToIRI(event, value)}
renderInput={params => (
<TextField
{...params}
{...input}
/>
)}
/>
)
}
}
Could really use some tips on how to make it simpler.
{value, label}selection, you can use lib:react-select