Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stateless function as component prop triggers a warning #748

Closed
elamperti opened this issue Jul 9, 2018 · 13 comments
Closed

Stateless function as component prop triggers a warning #748

elamperti opened this issue Jul 9, 2018 · 13 comments

Comments

@elamperti
Copy link

CodeSandbox demo: https://codesandbox.io/s/zqx94zxy0l

Following the example in the documentation, adding a component property raises an error in the console saying:

Warning: Stateless function components cannot be given refs. Attempts to access this ref will fail.

Check the render method of DayPickerInput.
in component (created by DayPickerInput)
in div (created by DayPickerInput)
in DayPickerInput (created by Example)
in div (created by Example)
in Example

I've noticed that @gengue had the same issue as well some months ago (Gitter message about it)

Transforming the component passed to the picker to a class seems to fix this problem (see this other example) although it doesn't look good and it's different from what the documentation suggests.

Could you provide a better solution or update the documentation to reflect this? Thanks in advance! :)

@gpbl gpbl added the bug:minor label Jul 9, 2018
@gpbl gpbl changed the title Setting component prop in DayPickerInput triggers an error Stateless function as component prop triggers a warning Jul 9, 2018
@gpbl
Copy link
Owner

gpbl commented Jul 9, 2018

Hey thanks for reporting this! The problem with stateless function is that we can't know how to focus the input field (reason we use a ref there).

This won't give any error from the v7.1.10, however the field won't be focused when the user picks a day from the calendar. We could add a condition to check if the component is stateless and skip the ref at all...

@gpbl gpbl added difficulty:easy good first issue Good for newcomers and removed difficulty:easy good first issue Good for newcomers labels Jul 9, 2018
@jaydp17
Copy link

jaydp17 commented Jul 30, 2018

Hey @gpbl was this fixed in v7.1.10?
As I'm still seeing the same warning in v7.1.10

@Sawtaytoes
Copy link

I'm also seeing the warning in v7.1.10.

Why not use document.querySelector instead of ref as an option?

It's not manipulating the DOM, just selecting a field that has the exact same name as you're passing to the input anyway. That way, I could give the component selector="[name='someFieldName']" or just name="someFieldName", and it would do something as simple as:

document
.querySelector('[name="someFieldName"]')
.focus()

Or is there some way I could just do this myself so long as the warning goes away?

@gpbl
Copy link
Owner

gpbl commented Aug 26, 2018

Why not use document.querySelector instead of ref as an option?

This can be a solution, but it is not easy as it seems – since it is possible to change the component of the input element, we really don't know what's inside there, which name it has (if it has one) etc.

A solution could be using findDOMNode, at

get input() {
   return React.findDOMNode(this).querySelector('input')
}

which will cover the most of the cases (but not the ones with multiple input fields in it).

IMHO the best solution would be to use the render props pattern by passing a getInput() prop that the user can customize for getting the input field. This will likely land to the next major release, though...

@Sawtaytoes
Copy link

You're right! That's significantly better.

My reason for not wanting any use of this or ref is because I'm using stateless functional components and prefer not writing components with a this or deal with ref if possible.

@gpbl
Copy link
Owner

gpbl commented Aug 26, 2018

Yeah that's legit! Thanks for the suggestion @Sawtaytoes.

I think however I'll change this behavior in the next major release, which will not require much refactoring from you... but it will protect others from breaking changes I can't see now using querySelector :)

@egloo8
Copy link

egloo8 commented Sep 5, 2018

Hey, I have the same issue! Any chance I could make this warning go away from my side, without editing the library?

@daeschwed
Copy link

@egloo8 the workaround suggested by @elamperti works great for me; create a component class for your input and pass that one as the component prop on DayPickerInput.

@alonbt
Copy link

alonbt commented Nov 1, 2018

I'm having trouble with the suggested solution since I need to pass a prop to that component:

class MyComp extends React.Component {

  rendertTinyComp () {
    return (<div>an improtant prop: {this.props.imporantProp}</div>)
  }

  render() {
    return (<DayPickerInput component={this.rendertTinyComp}/>) //will result the refs error
  }
}

If I try to define the component from the outsite I can do something like this:

return (<DayPickerInput component={<TinyComp imporantProp={this.prop.imporantProp} />) //will not accept a componet - expects a function

the only way to make it work is to somehow create a class component inside the myComp component which sounds like a bad practice and I'm not sure it's even possible.

This can be done with redux easily probably, but unfortunately I can't use redux in this specific scenario.

Does someone has an idea how to solve this ?

@asadsahi
Copy link

Just wanted to clarify if this issue conflicts with the documentation as well. Getting same error:

http://react-day-picker.js.org/api/DayPickerInput/#component

@mrbinwin
Copy link

mrbinwin commented Nov 23, 2018

This code works fine without any warnings:

import DayPickerInput from 'react-day-picker/DayPickerInput';

class Input extends React.Component {
    render() {
        return <input />;
    }
}

class DurationInput extends React.Component {
    render() {
        return (
            <DayPickerInput component={Input}/>
        );
    }
}

@matthewmcclatchie
Copy link

Stumbled across this today whilst looking for a solution to the same problem.

Following the guide in the docs and passing the props to the component and returning a new component with the props spread into it (`...props) resulted in the same error.

Both @elamperti and @mrbinwin 's solutions worked for me. In my case however, I was using a Styled Component as the input for the component prop and need to pass some extra props along.

In order to add these extra props, I used the inputProps prop (which I must have missed when looking at the docs) and everything now works!

@iamnnort
Copy link

iamnnort commented Jul 12, 2019

Hi @matthewmcclatchie, inputProps prop was added to the documentation (see http://react-day-picker.js.org/api/DayPickerInput/#inputProps)
Works for me

import DayPickerInput from 'react-day-picker/DayPickerInput';
import styled from 'styled-components';

const StyledInput = styled.input``;

const MyInput = React.forwardRef((props, ref) => {
  return <StyledInput ref={ref} {...props} />
});

const DatePicker = () => {
  return <DayPickerInput inputProps={{ name: 'myInputName' }} component={MyInput}/>
});

@gpbl gpbl closed this as completed Feb 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests