I am new in React. In my react component, I have an input, and i need to reset the value of input to "" when the user press space button.
You can consider the component as following:
import React,{Component} from 'react';
export default class InputReceiver extends Component{
render(){
return(
<div className="col-sm-10">
<input type="text" className="form-control" onChange={this.props.inputHandler}/>
</div>);
}
}
Is it true that, i have to make it in the action?
but the action does not understand the input.
Point:
I should not use jQuery.
Using React Hooks, you can do the following:
Use the onKeyDown attribute on < input /> field to record each key press. Check if the pressed key is a space ( ASCII value 32 in this case ), and reset the input field.
const InputField = () => {
const [inputValue, setInputValue] = React.useState("");
const handleInputChange = (e) => {
setInputValue(e.target.value);
};
const handleSpace= (e) => {
if (e.keyCode === 32) {
setInputValue("");
}
};
return (
<div>
<input
type="text"
value={inputValue}
onChange={handleInputChange}
onKeyDown={handleSpace}
/>
<p>Entered value: {inputValue} </p>
</div>
);
};
Note: KeyboardEvent.keyCode has been deprecated. Instead, use KeyboardEvent.key.
In the above example, it would be:
const handleSpace= (e) => {
if (e.key === " ") {
setInputValue("");
}
};
Use onKeyDown to call a function that detect the pressing of spacebar. If spacebar is pressed fire an action that reset the value of input.
Component
import React,{Component} from 'react';
import * as action from './path/to/action';
class InputReceiver extends Component{
detectSpacePresent = (e) => {
if(e.keyCode == 32) {
this.props.changeInputValue('');
}
}
render(){
return(
<div className="col-sm-10">
<input type="text" className="form-control" value={this.props.inputValue} onChange={this.props.inputHandler} onKeyDown={this.detectSpacePresent}/>
</div>);
}
}
function mapStateToProps(state) {
return {
inputValue: state.inputValue;
}
}
function mapDispatchToProps(dispatch) {
return {
changeInputValue: bindActionCreator(action, dispatch);
}
}
export default connect(mapStateToProps, mapDispatchToProps)(InputReceiver);
Action
export function changeInputValue(val) {
return {type:'CHANGE_INPUT_VALUE', data: val}
}
Reducer
export const = (state = {}, action) {
switch(action.type) {
case 'CHANGE_INPUT_VALUE':
return {inputValue: action.data}
}
}
You really don't need to have redux. People started taking redux for granted. You could simply use a onChange handler in the InputReceiver component and call the inputHandler from it. The example below should explain.
Hope it helps!
class InputReceiver extends React.Component{
constructor(props) {
super(props)
this.state = {
value : ''
}
this.onChange = this.onChange.bind(this)
}
onChange(e){
const val = e.target.value
const lastChar = val[val.length - 1] //take only the last character
if(lastChar === ' ') //check if the last character is a <space>
this.setState({value: ''}) //if yes, reset value
else
this.setState({value: val})//if no, save the value
this.props.inputHandler && this.props.inputHandler(e)
}
render(){
return(
<div className="col-sm-10">
<input type="text" className="form-control" value={this.state.value} onChange={this.onChange}/>
</div>);
}
}
class App extends React.Component{
inputHandler(e){
console.log('called inputHandler')
}
render(){
return <InputReceiver inputHandler={this.inputHandler} />
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
<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>
<div id="app"></div>
Related
I am trying to display input value on submit. But it seems to be not working. I don't have any errors but nothing being rendered. What is wrong with the code?
import React from 'react';
import { Component } from 'react';
class App extends Component {
constructor (props) {
super(props)
this.state = {
city : ""
}
}
handleSubmit = (event)=> {
event.preventDefault();
this.setState ({
city : event.target.value
})
}
render () {
return (
<div>
<form onSubmit={this.handleSubmit}>
<input type = "text" city = "city_name" />
<button type="submit">Get Weather</button>
{this.state.city}
</form>
</div>
)
}
}
export default App;
<form
onSubmit={e=>{
e.preventDefault()
console.log(e.target[0].value)
}}>
<input type="text"/>
<button type="submit">dg</button>
</form>
that works for me very well
Remember onSubmit target:
Indicates where to display the response after submitting the form. So you can get inner elements (and their corresponding values) like normal javascript code.
const city = event.target.querySelector('input').value
handleSubmit = (event) => {
event.preventDefault();
this.setState ({ city })
}
I guess you want it to get work like below. But this is not the only way to get it done.
import React from "react";
import { Component } from "react";
class App extends Component {
constructor(props) {
super(props);
this.state = {
city: ""
};
}
handleSubmit = (event) => {
const formData = new FormData(event.currentTarget);
event.preventDefault();
let formDataJson = {};
for (let [key, value] of formData.entries()) {
formDataJson[key] = value;
}
this.setState(formDataJson);
};
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<input type="text" name="city" />
<button type="submit">Get Weather</button>
{this.state.city}
</form>
</div>
);
}
}
export default App;
Code sandbox => https://codesandbox.io/s/eager-oskar-dbhhu?file=/src/App.js
I am new in React and want to develop easy app - there is input field from which I want to take values and render list. After added option in text field I want to update this list whith new option.
setState function does not work and I don't know how to connect input submit and list rendering. My code is below.
WaterApp.js
import React from 'react';
import AddWater from './AddWater';
import WaterElements from './WaterElements';
export default class WaterApp extends React.Component {
state = {
quantities: ['aaaaa', 'bbbbb', 'ccccc']
};
handleAddQuantity = (quantity) => {
this.setState(() => ({
quantities: ['ddddd', 'eeeee']
}));
console.log('works');
}
render() {
return (
<div>
<WaterElements quantities={this.state.quantities} />
<AddWater handleAddQuantity={this.handleAddQuantity} />
</div>
)
}
}
AddWater.js
import React from 'react';
export default class AddWater extends React.Component {
handleAddQuantity = (e) => {
e.preventDefault();
const quantity = e.target.elements.quantity.value;
console.log(quantity);
};
render() {
return (
<form onSubmit={this.handleAddQuantity}>
<input type="text" name="quantity" />
<input type="submit" value="Submit" />
</form>
)
}
}
WaterElements.js
import React from 'react';
const WaterElements = (props) => (
<div>
<p>Water Quantity:</p>
{
props.quantities.map((quantity) =>
<p key={quantity}>{quantity}</p>
)
}
</div>
);
export default WaterElements;
I expect list to be ddddd, eeeee at this moment.
You're never calling props.handleAddQuantity
export default class AddWater extends React.Component {
handleAddQuantity = (e) => {
e.preventDefault();
const quantity = e.target.elements.quantity.value;
props.handleAddQuantity(quantity)
};
render() {
return (
<form onSubmit={this.handleAddQuantity}>
<input type="text" name="quantity" />
<input type="submit" value="Submit" />
</form>
)
}
this.setState(() => ({
quantities: ['ddddd', 'eeeee']
}));
should be
this.setState({
quantities: ['ddddd', 'eeeee']
});
and after for add
this.setState({
quantities: [...state.quantities, quantity]
});
to update use this format
this.state({key:value});
not this.state(()=>{key:value});
handleAddQuantity = (quantity) => {
this.setState({
quantities: ['ddddd', 'eeeee']
}));
console.log('works');
}
I came across with this scenario where I want to "sanitize" the input before calling onChange, however even without re-render, the cursor moves to the end. why?
class Input extends React.Component {
state = { value: this.props.value };
onChange = e => {
let nextValue = e.target.value;
if (!/[0-9]/.test(nextValue)) {
this.setState({ value: nextValue });
}
};
render() {
console.log("render");
return (
<input type="text" value={this.state.value} onChange={this.onChange} />
);
}
}
ReactDOM.render(<Input value="type something here" />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
You can use onKeyPress to sanitize an input before onChange, without "side effects".
Code Sandbox: https://codesandbox.io/s/9jlm59n52r
import React from "react";
import ReactDOM from "react-dom";
class Input extends React.Component {
state = { value: this.props.value };
handleKeyPress = e => {
let keyPressed = e.key;
if (/[0-9]/.test(keyPressed)) {
e.preventDefault();
}
};
handleChange = e => {
this.setState({ value: e.target.value });
};
render() {
return (
<input
type="text"
value={this.state.value}
onKeyPress={this.handleKeyPress}
onChange={this.handleChange}
/>
);
}
}
ReactDOM.render(
<Input value="type something here" />,
document.getElementById("root")
);
EDIT:
Sanitize input on paste:
handlePaste = e => {
let pastedText = e.clipboardData.getData("text/plain");
if (/[0-9]/.test(pastedText)) {
e.preventDefault();
}
}
...
<input
...
onPaste={this.handlePaste}
...
/>
I would like to know how to have it where when I press enter on my keyboard, it logs whatever is in the input onto the console. Please help. Thanks!
import React, { Component } from 'react';
import './App.css';
class App extends Component {
onClick() {
alert("CLICKED");
}
onChange(eve) {
console.log(eve.target.value);
}
onSubmit() {
alert("SUBMITTED");
}
render() {
const list = ["Lebron", "Kobe", "Steph", "Kevin"];
return (
<div className="App">
<h1>{
list.map(listitem =>{
return (
<div onClick={this.onClick}>
{listitem}
</div>
)})
}</h1>
<form onSubmit={this.onSubmit}>
<input onChange={this.onChange} />
</form>
</div>
);
}}
export default App;
Please help!
Store the input value in a state variable onChange and then log it to the console onSubmit.
class App extends Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
}
onChange = event => {
this.setState({ value: event.target.value});
}
onSubmit = event => {
const { value } = this.state;
event.preventDefault();
console.log(value);
}
render() {
const list = ["Lebron", "Kobe", "Steph", "Kevin"];
const { value } = this.state;
return (
<div className="App">
...
<form onSubmit={this.onSubmit}>
<input onChange={this.onChange} value={value}/>
</form>
</div>
);
}
}
This doesn't work in react 16, but this jsfiddle works fine: https://jsfiddle.net/kp04015o/9/
Can any one debug this error why? Cannot read property 'value' of null, at handleChange = debounce(e => this.setState({searchTerm: e.target.value}), 1000);
import React from 'react';
import ReactDOM from 'react-dom';
const debounce = (cb, wait) => {
let timeout;
return function() {
let callback = () => cb.apply(this, arguments);
clearTimeout(timeout);
timeout = setTimeout(callback, wait);
}
}
class Debounce extends React.Component {
state = {
searchTerm: '',
};
handleChange = debounce(e => this.setState({searchTerm: e.target.value}), 1000);
render() {
return (
<div>
<input type="text" onChange={this.handleChange}/>
<div>Search Value 2: {this.state.searchTerm}</div>
</div>
);
}
}
ReactDOM.render(<Debounce />, document.getElementById('root'));
Read about Event Pooling
Here you have a working code:
class Debounce extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
state = {
searchTerm: '',
};
setSearchTerm = debounce((searchTerm) => this.setState({ searchTerm }), 1000);
handleChange(e) {
this.setSearchTerm(e.target.value);
}
render() {
return (
<div>
<input type="text" onChange={this.handleChange} />
<div>Search Value 2: {this.state.searchTerm}</div>
</div>
);
}
}
or nicer with ES7 decorators and decko module:
import { debounce, bind } from 'decko';
class Debounce extends React.Component {
state = {
searchTerm: '',
};
#debounce(1000)
setSearchTerm(searchTerm) {
this.setState({ searchTerm });
}
#bind
handleChange(e) {
this.setSearchTerm(e.target.value);
}
render() {
return (
<div>
<input type="text" onChange={this.handleChange} />
<div>Search Value 2: {this.state.searchTerm}</div>
</div>
);
}
}
I feel like I know this.
Try changing this:
<input type="text" onChange={this.handleChange} />
to either:
<input type="text" onChange={this.handleChange.bind(this)} />
or:
<input type="text" onChange={(e) => this.handleChange(e)} />
That is my gut reaction every time I see something of undefined with a React event, and because your default state is handled. If this works, it's because the execution context or lexical environment is in a different dimension than it might appear.