This is a set of React form field components which don't change their value programmatically when focused. It helps to build controlled inputs that don't annoy users.
Here is a simple example. It is a React application where a user can change his/her name. A name must not start or end
with a space and must be not more than 10 characters long. The user is typing I am typing a text
and pressing Tab.
Plain input | Friendly input |
---|---|
class App extends React.Component {
state = {
name: ''
};
setName = event => {
this.setState({
name: event.target.value
.trim().slice(0, 10)
});
};
render() {
return <input
value={this.state.name}
onChange={this.setName}
/>;
}
}
ReactDOM.render(<App/>, document.body); |
class App extends React.Component {
state = {
name: ''
};
setName = event => {
this.setState({
name: event.target.value
.trim().slice(0, 10)
});
};
render() {
return <reactFriendlyInput.Input
value={this.state.name}
onChange={this.setName}
/>;
}
}
ReactDOM.render(<App/>, document.body); |
There are several ways to install the components:
Simple
Download the plugin script and import it using a <script>
tag after the React
import.
<!-- React -->
<script type="text/javascript" src="//cdn.jsdelivr.net/npm/[email protected]/umd/react.production.min.js"></script>
<!-- React Friendly Input -->
<script type="text/javascript" src="//cdn.jsdelivr.net/npm/[email protected]/dist/react-friendly-input.umd.min.js"></script>
AMD/RequireJS
The script requires the following AMD modules to be available:
react
— React.
Installation:
require.config({
paths: {
react: '//cdn.jsdelivr.net/npm/[email protected]/umd/react.production.min',
'react-friendly-input': '//cdn.jsdelivr.net/npm/[email protected]/dist/react-friendly-input.umd.min'
}
});
define('myModule', ['react-friendly-input'], function (reactFriendlyInput) {
// ...
});
Node.js/NPM/Yarn/Webpack/Rollup/Browserify
Install the package:
npm install react-friendly-input --save
Require it:
const reactFriendlyInput = require('react-friendly-input');
The components are rendered like the plain React form fields. All the props are passed to the underlying DOM elements.
const {Input, TextArea, Select} = reactFriendlyInput;
ReactDOM.render(
<div>
<Input type="text" value="some value" />
<TextArea value="big text" rows="4" />
<Select value="1">
<option value="0">No</option>
<option value="1">Yes</option>
<Select>
</div>,
document.body
);
If a field is focused, the field value doesn't change when a new value is given through the props. The new value is applied as soon as the field loses the focus.
A component can be uncontrolled:
const {Input} = reactFriendlyInput;
return <Input defaultValue="initial value" />;
You can change a field value using the value
property. If the field is focused the value doesn't change.
const {Input} = reactFriendlyInput;
let input;
ReactDOM.render(<Input defaultValue="value1" ref={i => input = i} />, document.body);
input.value = 'value2';
You can set a new value despite the focus using the forceValue
method:
input.forceValue('value2');
If you have a component that acts like a form field:
- Its element has a writable
value
attribute - Has the
defaultValue
,onFocus
andonBlur
props that acts the same as in the<input>
component - Uncontrolled when doesn't receive the
value
prop
You can use the higher-order component function to make it friendly:
const {palInput} = reactFriendlyInput;
class CustomField extends React.Component {
// ...
}
const FriendlyCustomField = palInput(CustomField);
If you need to get a reference to the underlying element (e.g. to focus it), you have several options.
First is to use the friendly input input
property:
const {Input} = reactFriendlyInput;
return <Input ref={friendlyInput => friendlyInput.input.focus()} />;
Second is to use the inputRef
prop:
const {Input} = reactFriendlyInput;
return <Input inputRef={input => input.focus()} />; // String refs are not supported here
The source code is located in the src
directory. When you first download the code, install
node.js version 8 or greater, open a console, go to the project root directory and run:
npm install
Run to compile the source code:
npm run build
Run to test:
npm test
Compile the code before testing because the test uses the compiled code. An Internet connection is required to test because multiple React versions are downloaded while testing.
The project follows the Semantic Versioning.
MIT. See the LICENSE file for details.