Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom component value #277

Closed
martinwells opened this issue Nov 14, 2015 · 8 comments
Closed

Custom component value #277

martinwells opened this issue Nov 14, 2015 · 8 comments

Comments

@martinwells
Copy link

Hi, I built a custom tags editor component. When I submit a form I'd like to generate a custom value returned from the component (an array of tags for example). Do you have any examples of how to do this?

@erikras
Copy link
Member

erikras commented Nov 14, 2015

I have done it before wrapping a react-select component with multi enabled. react-select gave me back a delimited string, and I had something like:

const normalizeValue = val => multi && val ? val.split(delimiter) : val || null;
...
<Select
  ...other props
  onChange={changeValue => onChange(normalizeValue(changeValue))}
/>

Where onChange was the onChange passed to my component from redux-form. Does that makes some sense?

All you need to do to make an input component work with redux-form is to have value and onChange props.

@martinwells
Copy link
Author

Yes, that makes sense. Thanks. Only thing I'm not sure about is how the value property gets populated in my component?

@martinwells
Copy link
Author

I think I'm missing something obvious here. I have a complex component that has a state value which I want to connect to a redux-form onSubmit. Is there a function I can implement or a way of binding the state value to the redux form value?

@erikras
Copy link
Member

erikras commented Nov 16, 2015

I'm not following you exactly, but let me write some code and see if something clicks in your head.

class ProductPage extends Component {
  componentWillMount() {
    const product = API.loadProduct();
    this.setState({product: product});
  }

  render() {
    return <ProductForm
      initialValues={this.state.product}
      onSubmit={values => API.saveProduct(values)}/>;
  }
}

@reduxForm({
  form: 'product',
  fields: ['name', 'tags']
})
class ProductForm extends Component {
  render() {
    const {fields: {name, tags}, handleSubmit} = this.props;
    return <form onSubmit={handleSubmit}>
        <input type="text" {...name}/>
        <TagEditor {...tags}/> // passes name, value, onChange, among others
      </form>;
  }
}

class TagEditor extends Component {
  state = {
    value: this.props.value // initialize state from value prop given by redux-form
  }

  componentWillReceiveProps(nextProps) {
    this.setState({value: nextProps.value}); // update state when props change
  }

  updateValue(value) {
    this.setState({value: value});  // change local state
    this.props.onChange(value);     // notify redux-form
    // calling setState() might not be necessary, because onChange() will result in the
    // prop changing, which will trigger componentWillReceiveProps() and update the
    // local state, but that will be on the next render cycle
  }

  render() {
    const {value} = this.state;
    // render input and call this.updateValue() to update the value.
  }
}

@leozdgao
Copy link

@erikras I have the similar issue, and I tried your code which works good. But I'm not sure about onBlur, my TagInput has a inner input, and only change value when the comma is inputed. I wish the value of my TagInput is maintained by the inner state, not the inner input. But onBlur seems read my inner input value and try to update the value? It's very confusing.

--UPDATE--

It seems the onBlur handler on my inner input is a chained function which chained my inner handler and this.props.onBlur. But the custom onBlur handler should be allowed. So is there anyway to ban the redux-form onBlur handler? I try to set touchOnBlur to false, but it seems not work.

--UPDATE--

I think I fixed my issue, onBlur is same as onChange, just use this.props.onBlur(value) to notify redux-form. Hope it helps. @martinwells

@prokaktus
Copy link

prokaktus commented Apr 18, 2016

@martinwells looks like if you need preprocess your value, you should define onChange and onBlur. Docs already contains such example:

onBlur={event => onBlur(parse(event))}
onChange={event => onChange(parse(event))}

http://redux-form.com/5.0.1/#/examples/complex

I did this myself and it's works as expected.

If docs already contains example, then issue can be closed.

@godmar
Copy link

godmar commented Nov 18, 2016

Is this technique still relevant in redux-form 6.2? If so, could the example perhaps be updated and added to the documentation?

@lock
Copy link

lock bot commented Jun 2, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 2, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants