React final form - Unable to pass function to oChange prop - reactjs

I have a in a form using react final form. I'm trying to pass the value of the current input to a function thats used when the field value changes. However when I type, it's taking no input.
<Field name="myField">
{({ input, meta }) => (
<div>
<TextField
type="text"
name={input.name}
value={input.value}
onChange={() =>
handleChange(input.value)
}
label="Title"
/>
</div>
)}
</Field>
I have a function handleChange above the render method. All I want to do is console the current value, and use a setState hook to update a state variable.
function handleChange(item: string) {
setTitle(item);
console.log(item);
}
What am I doing wrong?

I would personally use a useEffect to achieve this, but the issue is that once you add your own useEffect onto it, then it overrides the default action which saves the form value to the form itself.
So first you still have to do the default onChange. And you want to take the value from the input field using e.target.value.
In your example, you are passing the value of the input field into your handeChange, but becuase you arent saving the value back into the input and the form, its always going to be empty.
<Field name="myField">
{({input}) => (
<div>
<TextField
name={input.name}
value={input.value}
onChange={(e, val) => {
console.log(e.target.value);
handleChange(e.target.value)
input.onChange(e.target.value);
}}
/>
</div>
)}
</Field>

Related

React final form initialValue clears onchange

I've been using react-final-form a while, and today i got caught up in a problem.
i want to be able to have a initialValue in a input field, and a checkbox next to it that clears the input field.
But when i run the onChange on the inputfield, that clears the checkbox because i don't wanna be able to let the user a checkbox value or a input value.
I hope someone understands the logic and can give me some hint on how to solve this.
I hav'nt tried mutators because i've never work with that, but if it would solve my case, i will look into it.
<Field
name={input-field}
component={InputField}
initialValue="500-"
/>
<OnChange name="input-field">
{() => {
props.form.change(checkbox, false);
}}
</OnChange>
</div>
<div>
<Field name={checkbox} component={CheckBox} type="checkbox" />
<OnChange name="checkbox">
{() => {
props.form.change(input-field, "");
}}
</OnChange>

how can I get the current value when I map an array in react

I want to get the current value and save it in the state but I get too many renders...
I'm mapping through data then I want to get render the UI based on that but also get the current data in the display so I can use it in another function in the same component.
{DATA.map(({ title, fields }) => {
setCurrentFields(fields.map((field) => field.name));
//this above cause the error but I want find a way to save that part of the data somewhere
return (
<Step label={title} key={title}>
<Box
textAlign="center"
p="3"
overflowY="auto"
height="100%"
>
{fields.map(
({
name,
validation = { required: true },
placeholder,
type,
}) => {
console.log(fields.length);
return (
<FormField key={name} errors={errors} name={name}>
<Input
id={name}
name={name}
placeholder={placeholder}
type={type}
{...register(name, validation)}
/>
</FormField>
);
}
)}
</Box>
</Step>
You can't do state management inside a render because state update will trigger a rerender every time you update. What you should do is iterate this DATA array somewhere outside the render and update states there. Useeffect is probably what you are looking for.
Also, take into consideration that you are rewriting the state for each element on the data array, so in the end you will only have the state of the final element saved in you currentValues state.

How to subscribe to field changes only after the form has been initialized in react-final-form

I have a react-final-form form, which needs to be initialized from the state. When one of the fields changes I want to reset the form to initial (empty) values. So I use subscription to the field's dirty state and if it changes I use OnChange to reset the form:
<Field name="option" subscription={{ dirty: true }}>
{({ input: { onChange } }) => (
<OnChange name="option">
{value => {
form.reset({
...initialValues,
option: value
});
}}
</OnChange>
)}
</Field>
But it doesn't work, as the form gets reset immediately after it has been initialized. Is there any way to separate these two events? So that I could reset the form only if its field has been modified by the user?
Here is the link to my codesandbox.
It doesn't work because <Field /> component will need to be rendered at least first time because its purpose is to rendering field UI not to hook callback. I'd suggest you to use <FormSpy /> instead because it intend for hooking callback even though it might hard for specific field
<FormSpy
subscription={{ dirtyFields: true }}
onChange={props => {
if (props.dirtyFields.option) {
form.reset({
...initialValues,
option:
form.getFieldState("option") &&
form.getFieldState("option").value
});
}
}}
/>
codesandbox
FormSpy

How to get value as string, not object

I use react-select inside my Redux form and I want me input filled with my value option, not the entire option.
Today, my form field is {'label':'text', 'value':'a'}. What I want is just a.
Here is my code:
[...]
renderField = data => {
return (
<Select
id={`xxx_${data.name}`}
name={data.name}
options={data.options}
value={data.input.value}
getOptionValue={option => option['value']}
onChange={(value) => data.input.onChange(value)}
onBlurResetsInput={false}
/>
);
};
[...]
render() {
return (
<Field
type={"select"}
component={this.renderField}
options={[{"label":"test1", "value":"a"}, {"label":"test2", "value":"b"}, {"label":"test3", "value":"c"}]}
name={"xxx"}
/>
);
};
So, I don't want the entire option in my form, but only the value of the option.
Do you know how to do that?
Thank you
EDIT
I tried to add a normalize on my field:
normalize={(value) => value.value}
It work but now, the display is wrong...

Mutator to covert text to uppercase

I tried different ways to implement mutator to convert text to uppercase as soon as user input text in the text field. But was not yet successful. The example provided by Erick seems correct, but maybe I am missing something.
/** Converts a form value to uppercase **/
const upper = ([name], state, { changeValue }) => {
changeValue(state, name, (value) => value.toUpperCase())
}
<Form
onSubmit={onSubmit}
mutators={{
...arrayMutators,
upper
}}
render={({
handleSubmit,
mutators: { push, pop, upper }, // injected from final-form-arrays above
pristine,
reset,
submitting,
values
}) => {
return (
<form onSubmit={handleSubmit}>
<div>
<label>Company</label>
<Field name="company" component="input" onChange={(e) => upper('company')} />
</div>
</form>
)}
}
/>
It's throwing an error when calling toUpperCase on value as value is coming undefined there. Really appreciate any help!
Update: 27-Oct-2018
I have realized we can use parser too, to solve this problem:
upper = value => {
return value ? value.toUpperCase() : ''
}
<Field name="company" component="input" parse={this.upper} />
Still looking for how mutator works and what's the error in my code.
Already Tried:
Mutate state based on existing fields
How to set/change Field value from external user action 🏁 React Final Form
As I know about react-final-form you can get this data directly
I will suggest, you can use this code
onChange={(event, value) => input.onChange(value.toUpperCase())}
https://codesandbox.io/s/0x9y71nwyp

Resources