I am new to react, I thought setting state will re-render react component. Did I miss something here, my text is not displayed until I call this.forceUpdate().
export default class Hello extends React.Component {
constructor(props){
super(props);
this.state = { value: ''};
this.handleChange = this.handleChange.bind(this);
}
render() {
return (
<div>
<input type="text" onChange={this.handleChange} />
<p> You entered {this.state.value} </p>
</div>
);
}
handleChange(event){
this.state = { value: event.target.value };
this.forceUpdate();
}
}
You should call .setState method instead of assign new value to this.state
handleChange(event){
this.setState({ value: event.target.value })
}
Related
I want to add React component to DOM. Next, I need to remove (hide) that. Then, I want to add (show) again that with all data entried.
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { value: '' };
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.setState({ value: e.target.value })
}
render() {
return <input type="text" onChange={this.handleChange} name="name" />
}
in parent Component:
<div>
{this.state.show && < MyComponent />}
<button onClick={() => { this.setState({ show: !this.state.show }) }} >change</button>
</div>
There will be few steps here...
Declare a state as const [show,setShow] = useState()
Now render the DOM element conditionally, like
show ? element1 : element2
The only solution is to use style.
We can send the status as a parameter to the component else component will be load again and data'll be clear
import React, { Component } from "react";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { value: "" };
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
console.log(this.state.value);
this.setState({ value: event.target.value });
}
render() {
return (
<form>
<label>
Name:
<input
type="text"
value={this.state.value}
onChange={this.handleChange}
/>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
console log screenshot
I'm getting first input value empty. I have different app. I'm basically try to doing tip calculator app. I don't need submit button. The user will enter a value, but it does not calculate correctly because the first value is empty. At the same time, it does not show the last value entered, only when clicked, all the entered values are correct. By the way, i got this form from React own site, but it's the same error that i encountered. Thank you!
Your console.log logs the value before you change it. Thus it will always be the previous value.
You also have to keep in mind that the Component.setState method might not execute immediately.
Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately.
Therefore you should use a callback. E.g.
handleChange(event) {
this.setState({ value: event.target.value }, () => {
console.log(this.state.value);
});
}
Here is an executable example. Click Run code snippet.
class App extends React.Component {
constructor(props) {
super(props);
this.state = { value: "" };
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value }, () => {
console.log(this.state.value);
});
}
render() {
return (
<form>
<label>
Name:
<input
type="text"
value={this.state.value}
onChange={this.handleChange}
/>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Set initial value to 0 so that it will not be empty.
this.state = { value: 0 };
Also move your console.log as callback function to setState so that you can see the updated value.
import React, { Component } from "react";
export default class App2 extends React.Component {
constructor(props) {
super(props);
this.state = { value: 0 };
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value }, () => {
console.log(this.state.value);
});
}
render() {
return (
<form>
<label>
Name:
<input
type="text"
value={this.state.value}
onChange={this.handleChange}
/>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
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>
);
}
}
import React from 'react';
import Child from './Child';
class Parent extends React.Component{
constructor(props){
super(props);
this.state = {
firstName: ""
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount(){
let fn = JSON.parse(localStorage.getItem("fir"));
if((localStorage.getItem("fir")!==undefined) && (localStorage.getItem("fir")!==null)){
this.setState({
firstName: fn
})
}
}
handleChange(e){
this.setState({
[e.target.name] :[e.target.value]
})
}
handleSubmit(){
localStorage.setItem("fir", JSON.stringify(this.state.firstName));
alert('submitted');
console.log(this.state.firstName)
}
render(){
return(
<div>
<p> Parent</p>
<Child
firstName={this.state.firstName}
handleChange={this.handleChange}
handleSubmit={this.handleSubmit}
/>
{this.state.firstName}
</div>
)
}
}
export default Parent;
2.
import React from "react";
class Child extends React.Component {
constructor(props) {
super(props);
this.state = {
firstName: props.firstName
};
}
render() {
return (
<div>
<p> Child</p>
<input
type="text"
name="firstName"
value={this.state.firstName}
onChange={this.props.handleChange}
/>
<button onClick={this.props.handleSubmit}> submit</button>
</div>
);
}
}
export default Child;
Here i want to update an input field in Child component, But i'm stucked. can anyone help to update that.
Change the below line in child
value={this.state.firstName}
to
value={this.props.firstName}
because firstname is being passed as a prop to child component
You need to pass the value you need to update has props then use that props in the value of your input in child component. I can see you already passing the firstName has a prop, you just to change state to props
<input
type="text"
name="firstName"
value={this.props.firstName}
onChange={this.props.handleChange}
/>
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