Reputation: 34013
I'm trying to create a reusable component that is an uncontrolled input. Normally this works fine, but I cannot get it to work with styled-components
applied to the child component (value
returns undefined
).
class Parent extends Component {
handleSubmit = (event) => {
console.log(this.firstName.value)
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>First Name</label>
<UncontrolledInput
defaultValue={'fish'}
inputType='text'
name='firstName'
inputRef={(element) => {this.firstName = element}}
/>
<button type="submit">
Submit
</button>
</form>
)
}
}
const StyledInput = styled.input`
border: 3px solid;
`;
const UncontrolledInput = (props) => {
const {name, inputType, defaultValue, inputRef} = props;
return (
<StyledInput
name={name}
type={inputType}
defaultValue={defaultValue ? defaultValue : ''}
ref={inputRef}
/>
)
};
Upvotes: 0
Views: 606
Reputation: 16309
styled-components
wraps elements into a react component. Passing a ref
prop to it will not give you the reference to the DOM element but to the wrapper component.
In the styled-components docs is described how to obtain a ref to the underlying DOM element:
Passing a ref prop to a styled component will give you an instance of the StyledComponent wrapper, but not to the underlying DOM node. This is due to how refs work. It's not possible to call DOM methods, like focus, on our wrappers directly.
To get a ref to the actual, wrapped DOM node, pass the callback to the innerRef prop instead.
So just change ref
to innerRef
on your <StyledInput>
component:
const UncontrolledInput = (props) => {
const {name, inputType, defaultValue, inputRef} = props;
return (
<StyledInput
name={name}
type={inputType}
defaultValue={defaultValue ? defaultValue : ''}
innerRef={inputRef}
/>
)
};
Here is a working example.
Upvotes: 1