-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Use forward refs in Components to access ref instances #3819
Comments
ref
instances
ref
instances
Here's a workaround that takes advantage of semantics 'as' prop and prop forwarding to give you access to the rendered DOM element. It'll work with any semantic components, you just need to pass in the render type, which in most cases will probably be the default. https://codesandbox.io/s/semantic-ui-react-refs-workaround-ibnnv |
@patrickp-dev Thanks for the workaround, but it seems to be causing some bad side-effects for me. I added an controlled Input and a useState hook to your example: https://codesandbox.io/s/semantic-ui-react-refs-workaround-2hr0e But with this workaround, the input loses focus after typing. Not sure what's happening, but I'm wondering if there's any other way to work around this. (Use case: I'm trying to capture keyboard events in a Modal, which means I need to focus() the modal's div when it's rendered. So I need a ref to focus. I saw some mention of a Ref component in other tickets, but it seems to be removed.) |
@jacobweber Hey jacob, had a look at your example. The lose of input focus was caused by the fact the 'as' prop was being reassigned a new instance of the higher order component that was returned by the forwardRefAs on each rerender, (my bad). All that's required is pulling the HOC instantiation out of the 'App' component so that it doesn't remount the entire form on each state change. I've updated your example to get it working and have update my original example. https://codesandbox.io/s/semantic-ui-react-refs-workaround-h0f64 |
@patrickp-dev Thanks! I'll give it a try. |
Summary:
|
Probably we should put a this notice about Semver or a badge in README.md.
@brianespinosa It's a good question. I don't think that it will be breaking change for function components as they don't have |
@mxschmitt BTW, for the original issue. <Ref innerRef={testRef}>
<Form />
</Ref> https://codesandbox.io/s/semantic-ui-react-refs-issue-u7zpv?file=/src/index.js |
I think now that we have released a full version we should stick with semantic versioning as I think that will be everyone's expectation once a full major version is out. I think it is also React team's recommendation for library authors that we should treat this as a breaking change and release a new major version. |
@layershifter looks great! For me it would be fine with closing this issue. 👍 |
@mxschmitt I will keep this issue opened for tracking work related to |
https://github.com/facebook/react/blob/2704bb5374e52ed548db96df2d975dae42158dfb/packages/react/package.json#L7 |
FYI: this #4039 PR restores docs for |
Small update there. SUIR 2.0.0 was released yesterday and I started to work on this item. I will stage a v3 branch soon.
|
@layershifter so in order to take care of that warning we should use functional components and React.forwardRef() ? BTW does this warning implies any security/performance issues? Is it ok to leave it in production code? |
Are there any progress on this ? |
I didn't understand if this had any solution, but anyway. I'm trying to use the react-hook-form. Directly with input this works:
Using the component does not work:
"Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?" |
const {register} = useForm ()
<Form.Input name="name" input={{ ref: register }} /> Should work for your case |
Warnings discussed in this PR are coming from SUIR, there is nothing that you can do with it until changes will be done on library side. |
Thanks @layershifter. And how would it look on other form components? Form.TextArea I was using html instead of components, but the select totally loses the style. |
This question is probably better off for StackOverflow but for components that don't have a native element to ref react-hooks-form provides Controller. Here is an example for something I needed: <Controller // react-hook-form (validation)
control={control}
name={name}
defaultValue={value}
rules={fieldValidators}
render={({ name: renderName, value: renderValue, onChange }) => (
<Form.Field error={error}>
<label htmlFor={name}>{label}</label>
<Select
className={className}
name={renderName}
defaultValue={renderValue}
placeholder={placeholder}
options={options}
error={error}
icon={icon}
onChange={(event, { value: newValue }) => onChange(newValue)}
/>
{error && (
<Label prompt className="ui pointing above prompt">
{error.message}
</Label>
)}
</Form.Field>
)}
/> |
Edit: Using the Controller with Select and Checkbox.
|
I had to go a bit further on an application I was working on. I was running into errors because I needed to make the focus exposed to react hook form, plus the added benefit of having it scroll to the offending field is really nice. It mostly involved similar things, but in this case, I ended up performing a query selector for the Select's input to focus on it. The others I made a wrapper for, I could just use the ref provided by the component https://gist.github.com/ZachHaber/7f443450bb83c92d2c8dbc74dd936f2a |
FYI, with v7 of React Hook Form (which is in beta right now), this situation is going to get slightly worse, in that the usage of refs is sort of implicit and hidden. With version 7, instead of explicitly passing Here's how it's supposed to work: import React from 'react';
import { useForm } from 'react-hook-form';
import { Form } from 'semantic-ui-react';
const MyForm = () => {
const { handleSubmit, register } = useForm();
return (
<Form onSubmit={handleSubmit(onSubmit)}>
<Form.Input
id="firstName"
label="First Name"
{...register('firstName')}
/>
<Form.Button content="Submit" />
</Form>
);
}; But because It seems like |
To add to the above, a similar scenario is with let input = React.useRef();
<Form.Field
required
control={CustomInput}
ref={input}
label='Required field:'
name='basic-input'
/>
// input: { current: undefined } |
@neutraali in your example, you would want to attach your ref to your CustomInput component and not the Form.Field wrapper. Even with |
@brianespinosa That doesn't seem right. Why couldn't FormField forward the ref to a custom control? |
Is there a list anywhere of which components currently forward correctly and which ones need to be updated? Otherwise it's a bit inconvenient to have to try out or look through all the code for each component. |
@sholladay If I am creating a custom input and place a ref on the FormField and not the custom input... I would be doing that because I explicitly want the ref on the FormField and not the custom input. This is a similar pattern with controlled components. The moment you reach in to component state, we can no longer reliably know what you want to do and you need to control it on your own.
@Hexavolus I do not think this exists. @layershifter was working on another major version bump that would encompass changing the rest of these warnings but it is not done yet. There will be updates here on this ticket when that does get released. |
@Hexavolus I don't think any SUIR components currently implement |
Ah, my mistake. The documentation said I assume this commonly comes up due to react-hook-form which does provide the |
Yeah, RHF is awesome and has become very popular, so that's a notable use case. Aside from that, there's also file inputs, where you need to use a ref to get access to the file for uploading, etc. |
Otherwise "findDOMNode is deprecated in StrictMode" warning is displayed in the console. Related issue: Semantic-Org/Semantic-UI-React#3819
I love Semantic UI React, and I, too, was having trouble integrating it with <Form.Field>
<Controller
name="username"
control={control}
render={({field: { ref, ...rest }, fieldState }) => {
return <Form.Input
label='Username'
icon='user'
iconPosition='left'
{...rest}
{...fieldState}
required error={errors.username ? true : false}
/> }
rules={{ required: true}}
/>
</Form.Field> By destructuring the If I had a lot of forms and/or form elements, wrapping these all the time would be tedious. But RHF does provide the I spent a good day trying to find this solution and figure out how it worked (I'm a DevOps guy--not a FE dev! 😋 So it took me a bit longer to figure this out). Anyway, HTH. It would be nice if we could just forward the ref--and if I'm reading this issue correctly, that work is underway. That'll be a great addition to this library. Thanks for all the hard work. It has been GREAT working with SUIR. |
The only thing that still throws this deprecation error in StrictMode for me out of Is there a work-around for this specific issue at the moment? I've found this thread great for information on getting around the other issues involving libraries that expect you to pass |
You can follow #4233 for progress 🎉 |
@fourpastmidnight Thank you very much for the example. I can confirm it works fine with RHF v7. I have been stuck here, getting slowly depressed how can I not just create a form using Semantic and RHF for over a week. I was trying to find a solution checking online (mostly outdated) examples and RHF issues. Apparently this ref-related issue was known on the Semantic side. Good thing people are working on it :) I was wondering if you could provide examples with select and checkboxes. I should be able to test them by modifying the snipper you provided, but a working example would be appreciated immensely, because I don't wanna give up on Semantic even for forms alone. Thanks in advance! |
Feature Request
Problem description
Currently, not all of components properly forward the passed in
ref
prop to the underlying component. This leads to end-users not being able to access the underlying DOM node and execute their browsers native functions.For example when you try to execute
checkValidity
on the form element itself.Proposed solution
Upgrade the components to forward refs: https://reactjs.org/docs/forwarding-refs.html
MVP
https://codesandbox.io/s/naughty-solomon-fqk4f?fontsize=14
Here you see who examples, the current
<Form>
component and the native browsers one. The ref instances are totally different.The text was updated successfully, but these errors were encountered: