React - issue with initialValues ant design when using referenced component - reactjs

Using ant design input and forms, I am having trouble using intialValues when a component is referenced in. In this case, I am trying to pass in CustomInput.js, a ant design Input, into my form as <Component/>. Everything works except the initialValues.
Any ideas what to do to make intialValues work?
https://codesandbox.io/s/initialvalues-forked-keftp?file=/index.js:382-414

You have to pass the props from your custom component down to Input, specifically the value prop:
function CustomInput(
{ field, value = "", onChange = (e) => {}, disabled, ...rest },
ref
) {
return (
<Input
ref={ref}
value={value}
onChange={onChange}
disabled={disabled}
{...rest}
/>
);
}
DEMO
Note: I'm unsure as to what your field prop is. Since it's not a supported prop as part of the component's API, I left it out.

Related

React-hook-form - Function components cannot be given refs

When trying to create a reusable input component that accepts a register react-hook-form Register function I get the error:
Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()
Following that, and solutions similar to this I ended up with this, however as you can see when clicking submit the values don't seem to get updated on the form.
I assumed this might've been because react-hook-form's internal ref is different from the one being forwarded, but looking at the docs it doesn't seem like there's a way to pass a ref.
Seeing how react-number-format binds well using a Controller I also tried that, but it still doesn't seem to work.
How would I go about creating this reusable component that can bind to different forms?
In your App.tsx file, change TextInput props as below.
<TextInput
placeholder="Text Input"
errors={errors.testInput}
register={register}
name={"testInput"}
options={ { required: true }}
// {...register("testInput", { required: true })} Don't destructure register here
/>
If register is destructured, then ref is passed directly to TextInput which is a function component and thus error in console.
register docs: https://react-hook-form.com/api/useform/register
No need to use Controller for native components. But in your code for ControlInput to work, pass onChange from field to input's onChange attribute.
render={({ field: { onChange, name, value } }) => (
<input
id={name}
// name={name}
type={fieldType}
placeholder={placeholder}
value={value||''}
onChange={onChange}
/>
)}

How to get focus from one textinput to another textinput?

I have created a custom text input, suppose it to be
Now I want to make user to get focused from one textinput to another. Make it as from
let {login,pass}=useRef(null)
<MyTextInput placeholder'login' ref={login} onSubmitEditing={()=>pass.focus()}/>
<MyTextInput placeholder='password' ref={pass}/>
Now i am working with functional components in react native And I have tried adding ref to both of it as above. But I am getting error as cannot cannot read property focus of undefined.
Can anyone help me adding focus with this kind of textinputs?
Here is a simple snippet that should work in your case assuming your custom MyTextInput supports the same props as TextInput
export default function App() {
const useranme = React.useRef(null)
const password = React.useRef(null)
return (
<View>
<MyTextInput onSubmitEditing={()=>password.current.focus()} ref={useranme} />
<MyTextInput ref={password} />
</View>
);
}

Pass "restProps" through React-Select

THE PROBLEM:
I have a simple Form Select Component. It has several props, and uses React Select V2, as the implementation layer. And I want to pass some extra props. Here is the code:
const SelectDropdownField = ({
prop1,
prop2.
...restProps
}: SelectProps): JSX.Element => (
<Field
name={name}
render={({
field,
form: { setFieldValue, setFieldTouched, errors, touched }
}: FieldProps<FormikValues>): ReactNode => (
return (
</div>
<ReactSelect
.. //someFieldsHere
{...restProps} // this doesn't work
/>
{JSON.Stringify({...restProps}, null, 2)} // this works
</div>
);
}}
/>
);
I am trying to pass the data-testid attribute. But if I pass it inside the ReactSelect, it doesn't work. Outside of it, it works just fine. Any ideas??
Unfortunately, after looking at the code, it seems impossible.
By checking here the render function of react-select, we can see that the only way we could add custom props is via the commonProps object. But checking each child component, there's no where it reaches the DOM. Only innerProps reaches the DOM but the library user has no control over it.

Rendering Formik Field outside Formik form

We have our own input components (like Checkbox, Textbox, or even CurrencyInput component)
We are now using Formik. So we replaced all <input... with <Field... in our components, eg.
const Checkbox = (props) => {
...
return (
<div className={myClass1}>
<Field type='checkbox' name={props.name} className={myClass2} ... />
<label ...>{props.label}</label>
</div>
)
};
Now the problem is, we can't have a standalone Checkbox outside a form anymore (eg. for an on-screen-only option). It will throw:
this.props.formik.registerField is not a function
We feel this is a dealbreaker. But before we ditch Formik and write our own form validation logics, I wonder if anyone else are having this dependency issue.
Is there really no way of rendering Formik Field outside Formik?
The Field component is what connects a form field to the Formik state. It uses context under the hood; Formik is the context provider and Field is the context consumer. Field is tied to Formik and has no use outside of it. For your use case where you want to render form fields that are sometimes connected to Formik and sometimes not, I would export two different components:
The base Checkbox component that has nothing to do with Formik. It should just use a normal input
A Field wrapper around that Checkbox component
While the Field component can take a type, causing it to render the corresponding input, it can also take a render prop to render whatever you want, and it is passed all of the state Formik manages for that field.
For example, your Checkbox and CheckboxField components could looks something like this:
const Checkbox = (props) => {
...
return (
<div className={myClass1}>
<input type='checkbox' checked={props.checked} onChange={props.onChange} />
<label ...>{props.label}</label>
</div>
)
};
const CheckboxField = (props) => {
return (
<Field name={props.name}>
{(field) => <Checkbox label={props.label} {...field} />}
</Field>
)
}
Now you use have two components that render exactly the same, but one is meant to be used within a Formik form (CheckboxField) and the other can be used anywhere (Checkbox).

Selecting an element in React in a stateless function component in React?

<TextField
onChange={props.onChangeTextField}
ref="questionInput"
style={styles.textField}
value={props.existingValue}
fullWidth={true}
/>
I was trying to give an input field in a stateless function component to be able to focus it when the component loads like this:
componentWillMount = () => {
this.refs.questionInput.focus();
console.log('test')
}
}
But I got the error:
Stateless function components cannot have refs.
So is there a way to focus an input field in React without a ref?
You should wrap your input component with forwardRef function. Something like this:
import * as React from "react";
const TextInput = React.forwardRef(
(props, ref) => <input ref={ref} {...props} />
);
export default TextInput;
Note that it will add a second argument to your functional component, which you should pass to the DOM element as ref prop.
Yes. However your method of using ref is really outdated. You should update to the latest version of React (currently 16.3.2) and follow the official documentation
function CustomTextInput(props) {
// textInput must be declared here so the ref can refer to it
let textInput = React.createRef();
function handleClick() {
textInput.current.focus();
}
return (
<div>
<input
type="text"
ref={textInput} />
<input
type="button"
value="Focus the text input"
onClick={handleClick}
/>
</div>
);
}
No, you need to change the functional component into a class.
You may not use the ref attribute on functional components because they don’t have instances
You should also use the newer callback API to set the ref:
ref={ref => { this.questionInput = ref }}
Or createRef for v16.3.
Adding the autoFocus prop to the input component might do the trick if you just want it to be focused on mount:
<TextField autoFocus ..restOfProps />

Resources