Textarea losing focus even if I try to keep it - javascript

I have a very interesting situation.
This is my component:
export const checkbox = ({ data }) => {
const inputRef = useRef(null);
console.log(inputRef); // Does not appear
return (
<FormGroup>
{data.data.map(item => (
<FormGroup>
<Input
ref={inputRef}
/>
</FormGroup>
</FormGroup>
);
};
It is a child of other component which basically get values and submits to form.
but to no avail..
How can I fix this? I just need it to keep the focus, so I can continue typing. Should I use React.memo() for this?
Also, please note that I have checked all the references I could find on SO and nothing helped. I have spent 3 days on this.

Based on our chat, the root cause was elements having a dynamic key prop which changed on each render. This was causing a new textarea element to be rendered with each change event and the new element didn't have focus.
The solution is to use a deterministic key which doesn't change between renders.

Related

Set Form data from sub components

im currently trying to create an dynamic form that uses a sub component to render out some input fields as createing them static would exceed a limit. I pass the states for the the form i made aswell as some date and the change form. But when i render the form as it does so fine! as soon as i change the state its sends a warning about uncontrolled components that you can read about it here
I have tried pre-setting all the fields with empty defaults but it doesnt help.
Am i doing it somewhat correct or totally wrong? or what is the correct way, or what am i doing wrong. thanks in adbance.
As for the code looks like this:
Edit.js
export default function InventoryItemEdit() {
const [form, setForm] = useState({});
function handleFormChange(e) {
setForm({ ...form, [e.target.name]: e.target.value });
}
const variants = (
<ItemVariants
form={form}
onChange={handleFormChange}
fields={form.sizes}
/* ^^ fields data fetched from the server i set via use effect hook when loading the page */
/>
);
const updateItem = async (event) => {
event.preventDefault();
/* Do form submit post */
};
return (
<form onSubmit={updateItem}>
<div>
<p htmlFor="name">Name</p>
<input
id="name"
name="name"
onChange={handleFormChange}
value={form.name}
type="text"
required
placeholder="Name of Item"
/>
</div>
{variants}
</form>
);
}
As for the sub component ItemVariants it looke like this
ItemVariants.js
export default function ItemVariants({
form = {},
onChange = '',
fields = [],
}) {
return (
<>
{fields.map((row, index) => (
<div>
<span>
{row.name}
</span>
<input
type="text"
id={`variant${index}`}
name={`variant${index}`}
onChange={onChange}
value={form[`variant${index}`]}
required
min="0"
placeholder="0"
defaultValue="0"
/>
</div>
))}
</>
);
}
Controlled component: is when your input value is coming from a single source of truth a state(meaning for an input value to change, you need to update the state holding the value)
Uncontrolled component: is when your input value is not coming from a state but rather it's coming from something we call useRef/createRef which helps to reference to react syntactic DOMNODE thus giving us the ability to interact with input in a false-actual-DOM(as if we were query an actual DOM input-node in pure-JS). Meaning if your input value is not coming from a state, it must come from a ref(ref.current.value which is equivalent to document.querySelector(theInputLocator).value).
Answer to your bug: I see that everything is okay, but the only issue is that you didn't set the initial state with the name key. Thats an analysing issue because in your code you doing [e.target.name]:e.target.value and the way inputs works generally is that event is triggered but must recent value is emitted when the event happens next. it works like a++.
Do this:
const [form, setForm] = React.useState({ name: '' });
The general rule of thumb is that always describe your form input keys when your inputs are predefine and not dynamic(in this case your name input is predefined).
So After digging reading this post i have to thank! #juliomalves for solution with value={form[`variant${index}`] ?? ''} or value={form[`variant${index}`] || ''}
I also found out i was accidently adding defaultvalue aswell as value which cannot be set at the same time i found out. After i tested it removed the default value and set it correctly to be a string! it now works like a charm!
Also thanks to #Emmanuel Onah for the explaination it really helped me understand more about the react states!
Thanks again for everyone that helped

Formik field loses focus when used with error props

When I type something in my custom field it loses focus and needs to be clicked again in order to add data, Below is the sandbox link to code. It only happens when I pass error and touched props to check for validation, If I remove that it works perfectly.
https://codesandbox.io/s/formik-example-forked-w0bub?file=/index.js
Browser I'm using is Chrom for windows
The input inside the functional component is recreated every time when there is state changes.
Read this blog post to know more the behaviour of nested functional components
To avoid recreation problem, you can follow the Formik example to create other functional component and use it inside your component.
const MyInput = ({ field, form, ...props }) => {
return <input {...field} {...form} {...props} />;
};
...
<Field
id="email"
name="email"
placeholder="Email"
component={MyInput}
/>
Here is the codesandbox for demo.

Error when setting an input in ReactJS, label is over / overwrites the value of the input set, using the material.ui

Good afternoon devs !!
I have a little problem, I'm using reactJS, and I'm using react-form-hook, in which I use an TextField from Material-UI. When I fill an input with name cep, it calls a function that sends the content from this to an api, which returns, content to fill the input there, The problem happens that when I try to set my inputs with the returned content. The Input label remains on the field, as in the case shown in the photo, in the last input. That came the answer.
the fields first with the setValues ​​of the react-form-hook, but the error persisted after I tried to set this way document.querySelector ('# inputStreet'). value = street;
Finally the way I decided was to create in this inputs that receive update a useState for each
const [srua, setSrua] = useState ('');
const [sbairros, setSbairros] = useState ('');
const [scity, setScidade] = useState ('');
const [sUF, setSUF] = useState ('');
Only in this way was he able to solve the problem of the label not being on the content of the input, as already exemplified in the photo in the last input, I believe this is not the most correct way, so I would like a help on how to solve this in a more efficient. just like that
Repository link.
The problem with your TextField is that the InputLabel does not shrink. the label shrinks when the TextField is in focus or when the value of the TextField is not empty.
But since you are setting the value programmatically, the input is not focused, the value is also not registered because it's uncontrolled which means the TextField keeps track and updates the value internally for you and ignore external value if provided.
In order to make the TextField controllable, as suggested from the name, you must take control of the TextField's value from the beginning which is what you did in the question.
You can also simplify this process by using react-hook-form's Controller. It's a wrapper component to help you pass common props to the controlled components
<Controller
render={({ onChange, onBlur, value, name }) => (
<TextField
onBlur={onBlur}
onChange={(e) => onChange(e.target.value)}
value={value}
name={name}
label="Email"
/>
)}
name="email"
control={control}
// need to initialize value to register the TextField as controlled
// if we don't provide, the default value is undefined, which means uncontrolled
defaultValue=""
/>
Which can be shortened to this
<Controller
render={(props) => <TextField {...props} label="Email" />}
name="email"
control={control}
defaultValue=""
/>
Live Demo

react-select function call on click event on the chip

Hi I am trying to change a state in my component when there is a click event on a particular chip rendered in the search bar. Is that possible to do?
I am aware of the multiValue multiValueLabel and I can for example change the background color of the chip with that, so I thought I could use those tags to change the state but I didn't have any luck.
I have attempted to find a solution with isSelected tag but I am always reading undefined in the states.isSelected when console.logged it.
I feel like I need a onClick() functionality somewhere but I can't figure it out. A bit of a guidance would be much appreciated!
I am sharing a live code here so maybe we can discuss over it.
if you want to validate if an option is selected you could use the prop: isOptionSelected
or
const onChange = selectedOptions => setSelected(selectedOptions);
with props
isMulti
value={selected}
onChange={onChange}
components={{
MultiValue: SortableMultiValue,
}}
You can attach onClick listener in MultiValueLabel component
<Select
isMulti={true}
components={{
MultiValueLabel: (props) => {
return (
<div onClick={() => console.log(props.data)}>
<components.MultiValueLabel {...props} />
</div>
);
}
}}
{...}
/>
Live Demo

input field not behaving as expected while making atom plugin?

I'm newbie in making atom plugins. I have to make a field which will take an input. I'm using etch for component management. In the render method, I've made this input field
<input
name={'component'}
type={'text'}
onchange={this.onInputChange}
value={this.componentName}
/>
I've made this onInputChange method which looks like :
onInputChange = (event) => {
this.componentName = event.target.value;
etch.update(this);
}
but I'm getting an event which comes after some time (kinda debounced event), furthermore I'm not able to delete the text from input. What is the right way to make an input.
<div class="native-key-bindings">
<input/>
</div>
Try wrapping it in this way. It will also fix the delete issue.

Categories