Set state not setting the state - reactjs

I have a very simple component with a single state, I initialize the state when component is created and try to change it when a form is submitted.
It doesn't work for some reason.
import React, { Component } from "react";
export default class AddTodo extends Component {
constructor() {
super();
this.state = {
submited: false
};
}
handleSubmit = event => {
this.setState = {
submited: true
};
alert("Submited state: " + this.state.submited);
event.preventDefault();
};
render() {
return (
<div className="container mt-3">
<form onSubmit={this.handleSubmit}>
<div className="input-group mb-3">
<input
type="text"
className="form-control"
placeholder="New Todo Description Here"
/>
<div className="input-group-append">
<button className="btn btn-primary" type="submit">
Add Todo
</button>
</div>
</div>
</form>
</div>
);
}
}

this.setState is a function, so call it like one using brackets ().
this.setState({
submited: true
});

import React, { Component } from "react";
export default class AddTodo extends Component {
constructor() {
super();
this.state = {
submited: false
};
}
handleSubmit = event => {
this.setState({
submited: true
},()=>{
alert("Submited state: " + this.state.submited);
event.preventDefault();
});
};
render() {
return (
<div className="container mt-3">
<form onSubmit={this.handleSubmit}>
<div className="input-group mb-3">
<input
type="text"
className="form-control"
placeholder="New Todo Description Here"
/>
<div className="input-group-append">
<button className="btn btn-primary" type="submit">
Add Todo
</button>
</div>
</div>
</form>
</div>
);
}
}

As you can see here setState is a function, but you're assigning a value to it.
The problem is here:
this.setState = {
submited: true
};
It should be:
this.setState({submitted: true}); // Mind the typo also
Just to make a quick note, the React team published react hooks in version 16.8 as a replacement to class components that have some drawbacks. I would give it a try, the docs are here.
With hooks your code would look like this:
import React, { useState } from 'react';
function AddTodo() {
// Declare a new state variable, which we'll call "count"
const [isSubmitted, setSubmission] = useState(false);
function handleSubmit(event) {
setSubmission(true);
event.preventDefault();
}
return (
<div className="container mt-3">
<form onSubmit={handleSubmit}>
<div className="input-group mb-3">
<input
type="text"
className="form-control"
placeholder="New Todo Description Here"
/>
<div className="input-group-append">
<button className="btn btn-primary" type="submit">
Add Todo
</button>
</div>
</div>
</form>
);
}

Related

My onchange method is not working in react

import React, { Component } from 'react';
import TaskBar from './Task';
class Todo extends Component {
state = {
todo: ''
}
changeHandler = (event) => {
console.log(event.target.value);
}
render() {
return (
<React.Fragment>
<div className="card">
<h5 className="card-header">Todo</h5>
<div className="card-body">
<h5 className="card-title">Task you want to do</h5>
<form>
<input type="text" className="form-control" value={this.state.todo} name="todo" onChange={(event) => this.changeHandler(event)} />
</form>
</div>
<button className="btn btn-primary">Go somewhere</button>
</div>
</React.Fragment>
)
}
}
export default Todo;
In the above code i don't know why i couldn't make any change
2) I am using Bootstrap cdn in my public folder and i am using these classes here
You forgot to set state inside your onchange handler.
import React, { Component } from 'react';
import TaskBar from './Task';
class Todo extends Component {
state = {
todo: ''
}
changeHandler = (event) => {
console.log(event.target.value);
this.setState({todo: event.target.value}) //you forgot to do this//
}
render() {
return (
<React.Fragment>
<div className="card">
<h5 className="card-header">Todo</h5>
<div className="card-body">
<h5 className="card-title">Task you want to do</h5>
<form>
<input type="text" className="form-control" value={this.state.todo} name="todo" onChange={(event) => this.changeHandler(event)} />
</form>
</div>
<button className="btn btn-primary">Go somewhere</button>
</div>
</React.Fragment>
)
}
}
export default Todo;
Link to a codesandbox example - https://codesandbox.io/s/jydjj?module=/example.js
Also currently your onchange uses an arrow function which creates a new function on every hit which is considered bad practice so i would suggest you to do this instead.
<input type="text" className="form-control" value={this.state.todo} name="todo" onChange={this.changeHandler} />

Why data is not rendered on refresh in react js with asynchronous call?

I am creating edit form.First i have to get data to edit form and i am calling it in componentDidMount().Please see code below.
import React from 'react';
import CompanyForm from './CompanyForm';
import { connect } from 'react-redux';
import { companyActions } from '../../../redux/actions/company-action';
class EditCompanyPage extends React.Component {
constructor(props){
super(props);
};
componentDidMount () {
const { id } = this.props.match.params
const { dispatch } = this.props;
dispatch(companyActions.getCompany(id));
}
render(){
const {editUser } = this.props;
return(
<div>
<h1>Edit Company</h1>
{
editUser && <CompanyForm handleActionParent={this.handleAction} companyDataFP={editUser} />
}
</div>
);
};
}
function mapStateToProps(state) {
const { editUser } = state.companyReducer;
return {
editUser
};
}
const EditCompany = connect(mapStateToProps)(EditCompanyPage);
export default EditCompany;
see code for CompanyForm component below:
import React from 'react';
class CompanyForm extends React.Component {
constructor(props){
super(props);
this.state = {
company :{
name : this.props.companyDataFP.name || '',
address1 : this.props.companyDataFP.address1 || '',
}
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
};
handleChange(e) {
const { name, value } = e.target;
const newState = Object.assign({}, this.state);
newState.company[name] = value;
this.setState(newState);
}
handleSubmit(e) {
e.preventDefault();
return false;
}
render(){
return(
<div className="col-md-12">
<form onSubmit={this.handleSubmit}>
<div className="row">
<div className="col-md-6">
<div className='form-group'>
<label htmlFor="name">Name</label>
<input type="text" name="name" className="form-control" onChange={this.handleChange} value={this.state.company.name} />
</div>
</div>
<div className="col-md-6">
<div className='form-group'>
<label htmlFor="address1">Address 1</label>
<input type="text" name="address1" className="form-control" onChange={this.handleChange} value={this.state.company.address1} />
</div>
</div>
</div>
<div className="row">
<div className="col-md-12">
<div className='form-group'>
<input type="submit" className="btn btn-info" value="submit" />
</div>
</div>
</div>
</form>
</div>
);
};
}
export default CompanyForm;
It works fine when i access this form with
<Link to="/edit-form/:id" >Edit</Link>
but when i refresh the current page then values are not rendering into form to edit.
I am using redux approach for state management, please guide me i am new to react.
Probably ComponyForm initializes form on its componentDidMount lifecycle function, so when editUser arrives nothing will change.
A way to handle this is changing:
<CompanyForm handleActionParent={this.handleAction} companyDataFP={editUser} />
to:
{editUser.name && <CompanyForm handleActionParent={this.handleAction} companyDataFP={editUser} />}

How to accept and pass two parameter as props

Hi I need to pass two parameters, to the class Chat. Currently it is getting only one parameter and displaying correctly.
const Chat = props => (
<div >
<ul>{props.messages.map(message => <li key={message}>{message}</li>)}</ul>
</div>
);
This Chat.js file is called from the Home.js. Suppose I need to pass the Chat component two parameters and I tried it like following.
import React, { Component } from 'react';
import { User } from './User';
import Chat from './Chat';
export class Home extends Component {
displayName = Home.name
state = {
messages: [],
names: []
};
handleSubmit = (message,name) =>
this.setState(currentState => ({
messages: [...currentState.messages, message],
names: [...currentState.names,name]
}));
render() {
return (
<div>
<div>
<User onSubmit={this.handleSubmit} />
</div>
<div>
<Chat messages={this.state.messages,this.state.name} />
</div>
</div>
);
}
}
In this scenario how should I change the Chat component to accept two parameters and display inside div tags.
This is what I tried. But seems it is incorrect.
const Chat = props => (
<div >
<ul>{props.messages.map((message, name) => <li key={message}>{message}</li> <li key={name}>{name}</li>)}</ul>
</div>
);
PS: The User Method
import * as React from 'react';
export class User extends React.Component{
constructor(props) {
super(props);
this.state = {
name: '',
message: ''
}
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
render() {
return (
<div className="panel panel-default" id="frame1" onSubmit={this.handleSubmit}>
<form className="form-horizontal" action="/action_page.php" >
<div className="form-group">
<label className="control-label col-sm-2" htmlFor="name">Your Name </label>
<div className="col-sm-10">
<input type="text" className="form-control" name="name" placeholder="Enter your Name" onChange={this.handleChange} />
</div>
</div>
<div className="form-group">
<label className="control-label col-sm-2" htmlFor="message">Message</label>
<div className="col-sm-10">
<input type="text" className="form-control" name="message" placeholder="Enter your Message" onChange={this.handleChange}/>
</div>
</div>
<div className="form-group">
<div className="col-sm-offset-2 col-sm-10">
<button type="submit" id="submit" className="btn btn-default">Submit</button>
</div>
</div>
</form>
</div>
);
}
handleChange(evt) {
this.setState({ [evt.target.name]: evt.target.value });
}
handleSubmit = (e) => {
e.preventDefault();
this.props.onSubmit(this.state.message, this.state.name);
this.setState({ message: "" });
this.setState({name:""});
};
}
You can do this by using separate attributes to pass different props. So for instance, you might revise your <Home/> components render method like so:
<Chat messages={this.state.messages} names={this.state.names} />
and then to access these two bits of data (messages and name) from inside the <Chat /> component you could do the following:
const Chat = props => (
<div >
<ul>{props.messages.map((message, index) => <li key={message}>
From: { Array.isArray(props.names) ? props.names[index] : '-' }
Message: {message}</li>)}
</ul>
</div>
);
Hope this helps!
You have to pass them separately:
<Chat messages={this.state.messages} name={this.state.name} />

Uncaught TypeError: Cannot create property 'empFirstName' on string ''

I'm getting a error like this in my ReactJS app,
Uncaught TypeError: Cannot create property 'empFirstName' on string ''
This error showing in browser console after i cleared textbox using clear button and tried to type.
code is below :
import React from 'react';
import fetch from 'isomorphic-fetch';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/css/bootstrap-theme.css';
import FormErrors from './FormErrors.js';
export default class EmployeeRegister extends React.Component {
constructor() {
super();
this.state = {
empFirstName: ''
}
this.handleChange = this.handleChange.bind(this);
this.clearFields = this.clearFields.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState({[name]: value})
});
}
clearFields() {
this.setState({empFirstName: ''})
}
render() {
return (
<div>
<div className="row">
<div className="col-sm-12">
<h2>Employee Register Form</h2>
</div>
</div>
<form>
<div className="row">
<div className="col-sm-6">
<div className="form-group">
<label htmlFor="empFirstName">First Name : </label>
<input type="text" className="form-control" id="empFirstNameTxt" value={this.state.empFirstName}
name="empFirstName"
onChange={this.handleChange}/>
</div>
</div>
</div>
<div className="row">
<input type="submit" value="Submit" className="btn btn-primary" id="submitBtn" />
<input type="button" value="Clear"
className="btn btn-warning"
onClick={this.clearFields}/>
</div>
</form>
</div>
);
}
};
Here name is of type const. For now change const to var. It should work
var name = target.name;
this.setState({[name]: value})
});

Cannot trigger component's function in my react app

I am currently working with react and I have runned into a problem this morning that i do not understand.
I am trying to handle a form submit from my component with a function by passing it in the onSubmit property but it does not trigger it. I then added a button to trigger a mock function with its onClick property, and i still got the same problem; it appears than I can't trigger my function and I cannot find any solution on the Google.
Here is my code so you can check it out:
import React from 'react';
import AgentsStore from '../stores/AgentsStore';
import AgentsActions from '../actions/AgentsActions';
class Agents extends React.Component {
constructor(props) {
super(props);
this.state = AgentsStore.getState();
this.onChange = this.onChange.bind(this);
}
componentDidMount() {
AgentsStore.listen(this.onChange);
}
componentWillUnmount() {
AgentsStore.unlisten(this.onChange);
}
onChange(state) {
this.setState(state);
}
handleSubmit(event) {
event.preventDefault();
var user = {};
user.name = this.state.newUser.name.trim();
user.lastname = this.state.newUser.lastname.trim();
if (user.name && user.lastname) {
AgentsActions.createUser(user);
}
}
onClick() {
console.log('clicked');
}
render() {
return (
<div /*className='container'*/>
<div className='alert alert-info'>
Hello from Agents
</div>
<div className='panel panel-default'>
<div className='panel-heading'>Create User</div>
<div className='panel-body'>
<form onSubmit={this.handleSubmit.bind(this)}>
<div className='form-group'>
<label className='control-label'>Name</label>
<input type='text'
className='form-control'
ref='nameTextField'
value={this.state.newUser.name}
onChange={AgentsActions.updateName} />
</div>
<div className='form-group'>
<label className='control-label'>Lastname</label>
<input type='text'
className='form-control'
ref='lastnameTextField'
value={this.state.newUser.lastname}
onChange={AgentsActions.updateLastname} />
</div>
<h4>Address</h4>
<button type='submit' className='btn btn-primary'>Submit</button>
</form>
<button onClick={this.onClick} className='btn btn-primary'>Submit</button>
</div>
</div>
</div>
)
}
}
export default Agents;
I do not know if I am missing something in my code or there is an error but i am kind of desperate. Also I am basing my code on another file that i have which is working just fine...
Thank you in advance for your time

Resources