Why value of input here at reactjs is undefined? - reactjs

I want to change state by the value of input but it is undefined.
It should work, the value is for every HTML tag so what is wrong with my code??
import React, { Component } from "react";
class App extends Component {
constructor() {
super();
this.state = {
firstName: " "
};
this.handleChange = this.handleChange(this);
}
handleChange(event) {
this.setState({
firstName: event.target.value
});
}
render() {
return (
<form>
<input
type="text"
placeholder="Firstname"
onChange={this.handleChange}
/>
<h1>{this.state.value}</h1>
</form>
);
}
}
export default App;

There's no value stored in your state, so it is undefined, and you do not correctly bind this to your handler. Output this.state.firstName instead:
import React, { Component } from "react";
class App extends Component {
constructor() {
super();
this.state = {
firstName: " "
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({
firstName: event.target.value
});
}
render() {
return (
<form>
<input
type="text"
placeholder="Firstname"
onChange={this.handleChange}
/>
<h1>{this.state.firstName}</h1>
</form>
);
}
}
export default App;

First try to bind this for handleChange using an arrow function. Also use the state variable to set the value property of the input .
Sandbox link: https://codesandbox.io/s/react-basic-example-qmyw5
import React, { Component } from "react";
class App extends Component {
constructor() {
super();
this.state = {
firstName: " "
};
}
handleChange = (event) => {
this.setState({
firstName: event.target.value
});
}
render() {
return (
<form>
<input
type="text"
placeholder="Firstname"
onChange={this.handleChange}
value={this.state.firstName}
/>
<h1>{this.state.firstName}</h1>
</form>
);
}
}
export default App;

Related

how to create a simple class-based react input component?

I am trying to create a text input component that has an initial value. The problem is that I can either have an initial value or I can change its value.
Im very beginner so please dont be rude.
This is my code:
import * as React from "react";
export class TextBox extends React.Component<{ value: any, onBlur?: Function, isAutoFocus?: boolean }> {
constructor(props) {
super(props);
this.state = {
value: props.value
}
/*this.setState({
value: props.value
})*/
}
public render() {
return <input /*value={this.props.value}*/ autoFocus onChange={(event) => { console.log("set new value"); this.setState({ value: event.target.value }) }} ></input>;
}
}
You just need to use the state instead of props to control the input's value
export class TextBox extends React.Component<{ value: any, onBlur?: Function, isAutoFocus?: boolean }> {
constructor(props) {
super(props);
this.state = {
value: props.value // this sets the initial value to what is passed from the props
}
}
public render() {
return <input value={this.state.value} autoFocus onChange={(event) => {this.setState({ value: event.target.value })}} ></input>;
}
}
class TextInput extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) { this.setState({value: event.target.value}); }
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} /> </label>
<input type="submit" value="Submit" />
</form>
);
}
}

rendering form fields normally vs rendering using a function

there are two ways i am rendering form fields
first way is directly putting them inside a render
form.tsx
import * as React from 'react';
export interface FormProps {
}
export interface FormState {
personal: any
}
class Form extends React.Component<FormProps, FormState> {
constructor(props: FormProps) {
super(props)
this.state = {
personal: {
firstName: "",
lastName: "",
}
}
}
handleChange = (event: any) => {
let personal = { ...this.state.personal };
personal[event.target.name] = event.target.value;
this.setState({ personal })
}
render() {
return (
<div>
<h1>first name</h1>
<input type="text" name="firstName" value={this.state.personal.firstName} onChange={this.handleChange} />
<h1>last name</h1>
<input type="text" name="lastName" value={this.state.personal.lastName} onChange={this.handleChange} />
</div>
);
}
}
export default Form;
the other way
form.tsx
import * as React from 'react';
export interface FormProps {
}
export interface FormState {
personal: any
}
class Form extends React.Component<FormProps, FormState> {
constructor(props: FormProps) {
super(props)
this.state = {
personal: {
firstName: "",
lastName: "",
}
}
}
count = 0;
handleChange = (event: any) => {
let personal = { ...this.state.personal };
personal[event.target.name] = event.target.value;
this.setState({ personal })
}
renderFields = () => {
this.count++;
console.log('render fields call count = ', this.count);
return (
<div>
<h1>first name</h1>
<input type="text" name="firstName" value={this.state.personal.firstName} onChange={this.handleChange} />
<h1>last name</h1>
<input type="text" name="lastName" value={this.state.personal.lastName} onChange={this.handleChange} />
</div>
)
}
render() {
return (
this.renderFields()
);
}
}
export default Form;
issue here is render fields being called on every state change and that is understandable but will this affect my performance
what i am going to do next is turn a json schema into form
checking what type of field it is and accordingly create the input field and many more things
example json is
"personal":{
"fields":[
{
"label":"name",
"type":"text"
},
{
"label":"id",
"type":"number"
}
]
}
It wont't actually hamper performance. Because there won't be actual dom manipulation if form's DOM attribute has not changed. To enhance more you can have pure component. To make custom formField where type and label can be changed. Have a custom form field component.

How to clear the inputs in function using React bootstrap typeahead

I am trying the clear the inputs in the function using following code.
import {Typeahead} from 'react-bootstrap-typeahead';
type requestState={
value:string[]
}
class Data extends Component<{},requestState> {
constructor(props){
super(props);
this.state = {
value: [],
}
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.typeahead.getInstance().clear();
}
render() {
return(
<Typeahead
ref={(ref) => this.typeahead = ref}
id="data"
labelKey="data"
multiple={true}
options={this.state.values}
placeholder="Choose a data.."
onChange={(e) => this.handleChange(e)}
/>
);
}
}
export default Data;
When I try using this code to clear the inputs at once, I am getting following error: "Property 'typeahead' does not exist on type 'Data'".
Could someone help me how to define typeahead property and what changes have to do to get this working.
This is a react ref issue and you just need to define the ref for use first.
Using classical definition:
class Data extends Component<{},requestState> {
constructor(props){
super(props);
this.state = {
value: [],
}
this.handleChange = this.handleChange.bind(this);
this.typeahead = null;
}
handleChange(e) {
this.typeahead.getInstance().clear();
}
render() {
return(
<Typeahead
ref={(ref) => this.typeahead = ref}
id="data"
labelKey="data"
multiple={true}
options={this.state.values}
placeholder="Choose a data.."
onChange={(e) => this.handleChange(e)}
/>
);
}
}
Using React.createRef
class Data extends Component<{},requestState> {
constructor(props){
super(props);
this.state = {
value: [],
}
this.handleChange = this.handleChange.bind(this);
this.typeahead = createRef<Typeahead>();
}
handleChange(e) {
this.typeahead.current.getInstance().clear();
}
render() {
return(
<Typeahead
ref={this.typeahead}
id="data"
labelKey="data"
multiple={true}
options={this.state.values}
placeholder="Choose a data.."
onChange={(e) => this.handleChange(e)}
/>
);
}
}
Refs and the DOM
This Changes worked for me in typescript to clear the inputs using React Bootstrap Typeahead
import React, { Component } from 'react';
import {Typeahead} from 'react-bootstrap-typeahead';
class Data extends Component<{},requestState> {
typeahead = React.createRef<Typeahead>();
constructor(props){
super(props);
this.state = {
value: [],
}
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.typeahead.current.state.selected= []
}
render() {
return(
<Typeahead
ref={this.typeahead}
id="data"
labelKey="data"
multiple={true}
options={this.state.values}
placeholder="Choose a data.."
onChange={(e) => this.handleChange(e)}
/>
);
}
}
export default Data;

React component: Simulate standard HTML <input/> API

I want to make a component with an API like any standard input element, meaning I want to use it like this: <CustomInput value={this.state.custom_input_state} onChange={this.handleChange} />
Here is what I have so far, but I have no idea how to
Make the custom components value changeable from the parent component
after it has been constructed
Make the parent's onChange handler function recieve a change event when the
custom component's value changes
Here is my test setup:
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
foo: 0
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.increment = this.increment.bind(this);
}
handleChange(event) {
this.setState({[event.target.name]: event.target.value});
}
handleSubmit(event) {
alert(this.state.foo);
event.preventDefault();
}
increment() {
this.setState({foo: this.state.foo + 1});
}
render() {
return(
<form onSubmit={this.handleSubmit}>
<div onClick={this.increment}>Increment from parent</div>
<CustomInput name="foo" value={this.state.foo} onChange={this.handleChange}/>
<input type="submit" value="Submit" />
</form>
)
}
}
class CustomInput extends React.Component {
constructor(props) {
super(props);
this.state = {
value: this.props.value,
};
this.increment = this.increment.bind(this);
}
increment() {
this.setState({value: this.state.value + 1});
}
render() {
return(
<React.Fragment>
<div onClick={this.increment}>Increment self</div>
<input name={this.props.name} value={this.state.value}/>
</React.Fragment>
);
}
}
You have to pass all the CustomInput props to the input element. In CustomInput component actually it not recieving the onChange event.
Pass the prop onChange event to input element
Form Component
class Form extends Component {
constructor() {
super();
this.state = {
foo: 'React'
};
}
handleChange = (event) => {
this.setState({
[event.target.name]:event.target.value
})
}
render() {
return (
<div>
<form>
<Custominput name="foo" onChange={this.handleChange} value={this.state.foo} />
</form>
{this.state.foo}
</div>
);
}
}
CustomInput Component
export default class CustomInput extends React.Component{
render(){
return(
<input {...this.props} />
)
}
}
demo link

How to make dependence between two form filters in ReactJS

I have three classes in my ReactJS app. Here they are :
class FirstFilter extends React.Component {
constructor() {
super();
this.state = {
val1: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
render() {
return (
<Label>
<Input type="select" value={this.state.value} onChange={this.props.handleChange}>
<option disabled selected value>Select plox</option>
<option value='Firdt'>First</option>
<option value='Second'>Second</option>
</Input>
</Label>
);
}
}
class SecondFilter extends React.Component {
constructor() {
super();
this.state = {
val2: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.val2});
}
render() {
return (
<Label>
<Input type="search" placeholder="Print somthing" value={this.state.value} onChange={this.props.handleChange}>
</Input>
</Label>
);
}
}
class Main extends React.Component {
constructor() {
super();
this.state = {
val1: '',
val2: ''
};
this.handleChangeVal1 = this.handleChangeVal1.bind(this);
this.handleChangeVal2 = this.handleChangeVal2.bind(this);
}
handleChangeUUID(event) {
this.setState({val1: event.target.value.toLowerCase()});
}
handleChangeOrigin(event) {
this.setState({val2: event.target.value.toLowerCase()});
}
render() {
return (
<div>
<Form inline>
<FormGroup>
<div>
<UuidRow handleChange = {this.handleChangeVal1} />
</div>
<div>
<OriginRow handleChange = {this.handleChangeVal2} />
</div>
</FormGroup>
</Form>
</div>
);
}
}
I want make SearchField from second filter empty when i check whatever in my DropDownList from first filter. When i only change value in my Main it's still leave typed text there. Maybe I doing something wrong and didn't understand basic hierarchy?
You should pass props to your child component, SearchField, when the state of the parent, Main, has been updated by the callback invoked by the DropDownList. The code in your example isn't consistent, so I can't guess what I need to change to help you, but here is a very basic example of how setting state in the parent via a callback event handler passed to one child (text input) can be used to set props on the second child (text area):
https://codesandbox.io/s/BLwl1y6j2
main.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import FirstChild from './FirstChild';
import SecondChild from './SecondChild';
class Main extends Component {
constructor(props) {
super(props);
this.state = {
val1: '',
};
}
// callback to pass as prop to child element text input
handleChangeVal1 = (event) => {
// sets parent state
this.setState({val1: event.target.value.toLowerCase()});
}
render() {
return (
<div>
<FirstChild handleChange = { this.handleChangeVal1 } value={ this.state.val1 }/>
<SecondChild value={ this.state.val1 }/>
</div>
);
}
}
render(<Main />, document.getElementById('root'));
FirstChild.js
import React, {Component } from 'react';
class FirstChild extends Component {
// input calls handleChange callback passed in props to modify parent component state
render() {
console.log(this.props.value);
return (
<input type="text" value={this.props.value} onChange={this.props.handleChange}/>
);
}
}
export default FirstChild;
SecondChild.js
import React, { Component } from 'react';
class SecondChild extends Component {
// render text area with value passed in props
render() {
console.log(this.props.value);
return (
<textarea value={this.props.value} onChange={this.props.handleChange}/>
);
}
}
export default SecondChild;

Resources