I don\'t know if I\'m doing this correctly... If I want to get value from an input I use this.refs.whatever.value.trim() but if that input is a stateless function component
as of react 16.8 you can use the useRef
hook,
from the docs:
useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component.
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` points to the mounted text input element
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
You can use ref
s inside stateless components.
Here is also my example fiddle that shows you how it works.
import React from 'react'
export default ({ onChange }) => {
let cityInput
const onSubmit = e => {
e.preventDefault()
onChange(cityInput.value)
}
return (
<form onSubmit={ onSubmit }>
<input type='text' placeholder='Enter City Name'
ref={ el => cityInput = el } />
<button>Go!</button>
</form>
)
}
Note: Although this is one way to do it, however, this approach is not recommended unless you really need it. Try to think about more on redesigning your React code instead of hacking it like this. You may read more about it here.
Edit: Looks like this is not the issue anymore, since new ideas on how to handle this situation arose since this answer was written. Refer to inanc's answer instead of this one.
Refs are unavailable in stateless components. From React Docs:
Because stateless functions don't have a backing instance, you can't attach a ref to a stateless function component. Normally this isn't an issue, since stateless functions do not provide an imperative API. Without an imperative API, there isn't much you could do with an instance anyway. However, if a user wants to find the DOM node of a stateless function component, they must wrap the component in a stateful component (eg. ES6 class component) and attach the ref to the stateful wrapper component.
@inanc, show good method, but I propose an alternative way to use event target to get the DOM element reference. As you are using the form element, you can name your input elements and use it to access the form object.
const onSubmit = fn => e => {
e.preventDefault()
const city = e.target.city.value // Access elements through `form`
if (city) {
fn(city)
}
}
const MyComponent = ({
onChange
}) => {
return (
<div>
<form onSubmit={onSubmit(onChange)}>
<input type='text' name='city' placeholder='Enter City Name' />
<button>Go!</button>
</form>
</div>
)
}
You can't use refs in stateless react components (+1 to Moti Azu for his snippet from the documentation).
You can use multiple techniques to get stuff in/out of stateless components (without using Ref or use class components), I have created the snippet below to illustrate
try it out & let me know if you still have a problem, enjoy...
// Stateless Component (just a <div> component with prop)
const StatelessComponent = props => (
<div>{props.label}</div>
);
// Stateless input Component
const InputComponent = props => {
return (
<input
value={props.name}
onChange={props.handleChange}
/>
);
};
// Parent Class Component
class ParentComponent extends React.Component {
state = {
firstName: "HELCODE"
};
handleChange = event => {
this.setState({
firstName: event.target.value,
});
};
render() {
const {title} = this.props;
console.log("rendered");
return (
<div>
<h3>{title}</h3>
<StatelessComponent
label="This is a label passed to a stateless component as prop"
/>
<br/>
<InputComponent
name={this.state.firstName}
handleChange={this.handleChange}
/>
<p>{this.state.firstName}{this.state.lastName} can read stuff from stateless components withough Ref using States</p>
<br/>
</div>
);
}
}
// Render it
ReactDOM.render(
<ParentComponent title="Parent Component" />,
document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Nowadays, you would want to avoid to use the ref attribute to get values from input fields. Instead you should use React's local state. The ref attribute is reserved for only a few use cases: