Html element set autofocus dynamically in React - reactjs

I have two sibling component.
one component contains textbox,checkbox,dropdown controls in it.
another component contains Kendo Grid.
whenever user clicks on grid row i want to set focus on one of the element in above
component which include textbox.
Approach used:
1.I don't want to use ref as i have multiple controls in one component.
2.I have dynamically added autofocus attribute to input element.

Disclaimer: I am not sure if these solutions are best practices in React
There are 2 approaches for this, both using refs, but with smarter implementations:
Create a wrapper around the inputs and assign refs to it. Whenever you want to focus on an input, simply use wrapperRef.querySelector('[name=yourInput]). Working example: https://codesandbox.io/s/195kkrpvq
Create an object which stores the name of the fields as keys and their refs as values. Simply use this.yourRefsObject[yourInputName].focus() to focus on an input. Working example: https://codesandbox.io/s/61jl7q9v43
Again, I am not certain whether these implementations are best practices, but they should do the job for now

Related

always lift up states of react child components?

My react-materialUI app has multiple dialogs, and some of these dialogs are containing the same mui data grid (a list of projects).
Example: a save project dialog. This dialog contains this mui data grid and a mui text field, both as child components.
By clicking on a row in the data grid, I want to set the content of the text field to the value of the selected row.
To accomplish this, I could lift up the value state of the text field and the selectedRow state of the data grid to the save dialog.
somehow I find it hard to understand that a supposedly reusable component isn’t handling their state by itself.
Is lifting states up really the best practice or is there something basic I overlooked?
If some behavior in the data grid should affect the value of the text field, you probably need to lift the state for that text value.
But you might not need to lift the state for the data grid. Instead, you could pass an onSelect prop which you use to set the text value, something like:
<DataGrid onSelect={(project) => setText(project.name)} />
Further reading
The beta React docs have great content on such topics, e.g. https://beta.reactjs.org/learn/thinking-in-react#step-4-identify-where-your-state-should-live

Which form is best for React and ReactNative, Formik vs React Hook Form vs React Reactive Form?

I am working on an application having nested forms. I am confused about which of them is best. I worked on react-reactive-form and it fulfils all the requirements of my app but has some issues with nested structure, especially with FormArray(to add new, prefill form array and delete the array element from a particular index). Basically, I need to do some extra code to achieve these.
After this, I saw lots of people using "Formik", especially when working with React. I'm new to Formik, I didn't know whether it's better in performance or not. Also, I didn't see any article that explains their technical performance part.
There is just a downloads comparison I found:: https://npmtrends.com/formik-vs-react-reactive-form
Formik: https://github.com/jaredpalmer/formik
React Reactive Form: https://github.com/bietkul/react-reactive-form
or React Hook Form:: https://www.npmjs.com/package/react-hook-form
My requirements:
need to use multiple and nested form structures inside my application.
require form validations of change, on blur or submit
handle data in the array where I can add new items dynamically, and also delete, add and update anything.
Most important:: Can pass controls to another component as reactive form does. This means if we want to create a form in the parent and then subdivide the form sections into components where we can pass that section form field controls to the child component and still after on change can get complete form values at one place that is at parent component.
Which of them is best in terms of performance, and can achieve all the parts easily I have mentioned.
use react-bootstrap for Form, Input, Button, etc

Hook re-render whole page on single change in a sub component

I create 2 Text Boxes one with hook and the another one with the old style, now in Hook mode when the user input change the textbox value the whole page rendered, but with old style there only the text-box rendered not the whole page, if you have the complex page with many objects like (Data Table, form, buttons, inputs, etc..) the single change on one of these components forced to re-render everything and it decease performance, for example typing in the text-box take time to effect on page and the delay time is more than user typing speed.
the one workaround solution is using the callbacks and useMem but if the page is complex(lots of objects as described, and all of these objects has many properties the callback and useMem is very very complicated to handle single object property.
SandBox Example
This is exactly how react hooks should work. what will cause a rerender in react? two things:
change in props
change in hooks or say in a better way hooks state
in the second case, the useInput state is changing so that causes a rerender and it's absolutely normal behavior. I think using custom hook in that way is not a good practice.
I recommend reading this article for more information on react rendering: https://www.codebeast.dev/usestate-vs-useref-re-render-or-not/

How can I find and click a button that has no text using React Testing Library?

Many React Testing Library examples show how to find and click a button using the getByText query, as in:
fireEvent.click(getByText("Create"))
OR
userEvent.click(getByText("Create"))
However, it's common to have buttons with no text and only SVG icons, like Material UI's icon buttons or floating action buttons. Is there a recommended way to query for and click buttons like these? For context, I'm using the higher-level events provided by the companion user-event library.
For icon buttons, add an aria-label attribute like below:
<button aria-label='edit'>
<edit-icon />
</button>
Then in your test, pass the accessible name when calling getByRole()
screen.getByRole('button', {
name: /edit/i
})
From the docs:
The accessible name is for simple cases equal to e.g. the label of a
form element, or the text content of a button, or the value of the
aria-label attribute.
There are several ways to query an element, without seeing your hierarchy of elements, it's hard to say. But, there are several ways to query an element, an alternative to using getByText() could be getByRole('button'). If you want to add a data-testid to the element you could use getByTestId(). There are some more available queries found here: https://testing-library.com/docs/dom-testing-library/api-queries
There are a bunch of different ways to do it, including everyone's favorite fallback, data-tested. But if you're using Material UI, you might be looking for the most "MUI" way to do this. Two ideas:
The MUI documentation shows all its buttons wrapped with a label element with an htmlFor property. You could do this and then use getByLabelText()
Your icon buttons probably have (and should!) a tooltip, and the tooltip text is probably coming from a title property. Then you can get the button with getByTitle().
For me non of above answers works, what is worked for me is:
screen.getByRole('button', { name: /<icon-file-name>/i });
In my case the button with only svg file.
The best possible way of finding an element is to simulate the most User oriented approach. So probably User expects the role button and then searches for an icon in your case. That's where semantic HTML plays a role for elements structure inside your component.
MUI buttons also implement a name attribute for some icon buttons used inside another component e.g. Select and I strongly recommend using this attribute for testing purpose.
Please remember that, your tests should be unaware of implementation, so identification should rely on name, role, label and other "natural" attributes. But if that is not possible using data-testid should be your last resort.
A very good overall approach (not only for icon buttons) is to specify a name property alongside role in getByRole query:
const listOpenButton = screen.getByRole("button", { name: /open/i });
Also a data-testid approach:
const listOpenButton = screen.getByTestId("myButtonId");

Extjs checkboxes inside basic form

I have a basic form inside a window. This form has several check boxes and I need to some how be able to select all with another checkbox. How am I supposed to access these checkbox types. I am trying to get reference to "this" and then this.getForm().getFieldValues() but is there a better way to do it, as I only need to get the checkboxes and not other fields.
Thanks,
SS
By default ExtJs fields don't have a getForm() method to get access to their parent. However, you can use this override to add this method. Once you've got the form, you can get access to any field you like, which should let you do what you describe.

Resources