One input component but different states for each occurrence - javascript

I have created a component element. I am using it in a form.
I put the state in the class for the input component and when i do console log and they all seem to share the same state? is this normal. will need to post the values into laravel api and store to mysql next. is the following correct or do i need to create an input component for each field i require. Eg. one for name, one for surname one for telephone one for email etc:
import React from 'react';
import styles from './Input.module.scss';
export class Input extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: ''
}
this.onInputChange = this.onInputChange.bind(this);
}
onInputChange(e) {
this.setState({ inputValue: e.target.value });
}
render() {
console.log(this.state.inputValue)
return (
<div className={styles.container}>
<label htmlFor={this.props.id} className={styles.label} > {this.props.label} </label>
<input
id={this.props.id}
className={styles.input}
type="text"
value={this.state.inputValue}
onChange={this.onInputChange}
/>
</div>
);
}
};
reusing same component here:
render() {
return (
<div className={styles.contactForm} >
<form onSubmit={this.onFormSubmit}>
<div className={styles.contactBlock} >
<div className={styles.header} onClick={this.onStepOneClick} >
<BoxHeader title="Step 1: Your Details" />
</div>
<div className={styles[this.state.stepOne]}>
<div>
<Input type="text" label="First Name" id="name" />
<Input type="text" label="Surname" id="surname" />
</div>
<div>
<Input type="email" label="Email Address" id="email" />
</div>
<div className={styles.button} onClick={this.onStepOneClick}>
<Button innerHTML="Next >" />
</div>
</div>
</div>
<div className={styles.contactBlock} >
<div className={styles.header} onClick={this.onStepTwoClick} >
<BoxHeader title="Step 2: More Comments" />
</div>
<div className={styles[this.state.stepTwo]}>
<div>
<Input type="tel" label="Telephone Number" id="tel" />
<Select label="Gender" id="gender" >
<option> Male </option>
<option> Female </option>
<option> Other </option>
</Select>
</div>
<div>
<Date label="Date of Birth" id="dob"/>
</div>
<div className={styles.button} onClick={this.onStepTwoClick}>
<Button innerHTML="Next >" />
</div>
</div>
</div>
<div className={styles.contactBlock} >
<div className={styles.header} onClick={this.onStepThreeClick} >
<BoxHeader title="Step 3: Final Comments" />
</div>
<div className={styles[this.state.stepThree]}>
<div className={styles.textArea}>
<Textarea label="Comments" id="comment" />
</div>
<div className={styles.submit}>
<Submit innerHTML="Next >" />
</div>
</div>
</div>
</form>
</div>
);

Yes, for each field you would need to create a new input. This can be within same or new component whichever you prefer.

Related

Doing real-time calculations in a form in react js components

I'm a new user to React and I'm having trouble with my app.. Basically I want to do some calculation when the user input some values it dynamically outputs the amount. The calculation should add the packaging amt with transport amt and subtract the discount amt, the result is then added to the product of kgs with price per kg to show the total amt. . If anyone can help me with this it would be very much appreciated. My code is included below `
import React from "react";
import APIHandler from "../utils/APIHandler";
import { Link } from "react-router-dom";
import AutoCompleteCustomer from "../components/AutoCompleteCustomer";
class HomeComponent extends React.Component {
constructor(props) {
super(props);
this.formSubmit = this.formSubmit.bind(this);
}
state = {
errorRes: false,
errorMessage: "",
btnMessage: 0,
sendData: false,
farmerlist: [],
customersDetails: [{
phone: "",
name: "",
}],
dataLoaded: false,
value: ""
};
async formSubmit(event) {
event.preventDefault();
this.setState({ btnMessage: 1 });
var apiHandler = new APIHandler();
var response = await apiHandler.saveOrdersData(
event.target.phone.value,
event.target.id.value,
event.target.town.value,
event.target.region.value,
event.target.kgs.value,
event.target.packaging.value,
event.target.discount.value,
event.target.transport.value,
event.target.comment.value,
event.target.farmer_id.value,
event.target.price.value,
event.target.amount.value,
);
console.log(response);
this.setState({ btnMessage: 0 });
this.setState({ errorRes: response.data.error });
this.setState({ errorMessage: response.data.message });
this.setState({ sendData: true });
}
//This Method Work When Our Page is Ready
componentDidMount() {
this.LoadFarmer();
}
async LoadFarmer() {
var apihandler = new APIHandler();
var farmerdata = await apihandler.fetchFarmerOnly();
this.setState({ farmerlist: farmerdata.data });
}
showDataInInputs = (index, item) => {
console.log(index);
console.log(item);
this.setState.customersDetails[index].phone = item.phone;
this.setState.customersDetails[index].id = item.id;
}
viewRequestDetails = (request_id) => {
console.log(request_id);
console.log(this.props);
this.props.history.push("/ordersDetails/" + request_id);
};
qtyChangeUpdate = (event) => {
var value = event.target.value;
this.state.total =
((parseInt(this.state.packaging) +
parseInt(this.state.transport) -
parseInt(this.state.discount)) +
(parseInt(this.state.kgs) * parseInt(this.state.price))) * value;
this.state.amount = value;
this.setState({});
};
render() {
return (
<section className="content">
<div className="container-fluid">
<div className="block-header">
<h2>MANAGE ORDERS & CUSTOMERS</h2>
</div>
<div className="row clearfix">
<div className="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div className="card">
<div className="header">
<h2>Add Order</h2>
<ul className="header-dropdown m-r--5">
<Link to="/addcustomer" className="toggled waves-effect waves-block">
<button className="btn btn-primary m-r-15 waves-effect">
Add Customer
</button>
</Link>
</ul>
</div>
<div className="body">
<form onSubmit={this.formSubmit}>
{this.state.customersDetails.map((item, index) => (
<div className="row" key={index}>
<div className="col-lg-6">
<label htmlFor="email_address">
Phone No.{" "}
</label>
<div className="form-group">
<div className="form-line">
<AutoCompleteCustomer
itemPostion={index}
showDataInInputs={this.showDataInInputs}
/>
</div>
</div>
</div>
<div className="col-lg-6">
<label htmlFor="email_address">Customer Name</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="id"
name="id"
className="form-control"
placeholder="Enter Customer Name"
defaultValue={item.id}
data-index={index}
/>
</div>
</div>
</div>
</div>
))}
<div className="row">
<div className="col-lg-4">
<label htmlFor="email_address">Town</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="town"
name="town"
className="form-control"
placeholder="Enter Customer Town"
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Region</label>
<div className="form-group">
<div className="form-line">
<select id="region" name="region" className="form-control show-tick">
<option value="1">Nairobi</option>
<option value="2">Nyanza</option>
<option value="3">Central</option>
<option value="4">Coast</option>
<option value="5">Eastern</option>
<option value="6">North Eastern</option>
<option value="7">Western</option>
<option value="8">Rift Valley</option>
</select>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Kgs : </label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="kgs"
name="kgs"
className="form-control"
placeholder="Enter Quantity."
defaultValue={this.state.kgs}
onChange={this.qtyChangeUpdate}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Packaging</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="packaging"
name="packaging"
className="form-control"
placeholder="Enter Amount"
defaultValue={this.state.packaging}
onChange={this.qtyChangeUpdate}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Discount.</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="discount"
name="discount"
className="form-control"
placeholder="Enter Discount."
defaultValue={this.state.discount}
onChange={this.qtyChangeUpdate}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Transport</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="transport"
name="transport"
className="form-control"
placeholder="Enter Transport."
defaultValue={this.state.transport}
onChange={this.qtyChangeUpdate}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Comment</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="comment"
name="comment"
className="form-control"
placeholder="Enter Comment"
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Farmer Name</label>
<div className="form-group">
<select className="form-control show-tick"
id="farmer_id"
name="farmer_id"
>
{this.state.farmerlist.map((item) => (
<option key={item.id} value={item.id}>
{item.name}
</option>
))}
</select>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Price per Kg</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="price"
name="price"
className="form-control"
placeholder="Enter Price"
defaultValue={this.state.price}
onChange={this.qtyChangeUpdate}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Amount</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="amount"
name="amount"
className="form-control"
placeholder="Enter Amount"
value={this.state.amount}
onChange={this.qtyChangeUpdate}
/>
</div>
</div>
</div>
</div>
<br />
<button
type="submit"
className="btn btn-success m-t-15 waves-effect "
disabled={this.state.btnMessage === 0 ? false : true}
>
{this.state.btnMessage === 0
? "Add Order"
: "Adding Order Please Wait.."}
</button>
<br />
{this.state.errorRes === false &&
this.state.sendData === true ? (
<div className="alert alert-success">
<strong>Success!</strong> {this.state.errorMessage}.
</div>
) : (
""
)}
{this.state.errorRes === true &&
this.state.sendData === true ? (
<div className="alert alert-danger">
<strong>Failed!</strong>
{this.state.errorMessage}.
</div>
) : (
""
)}
</form>
</div>
</div>
</div>
</div>
</div>
</section>
);
}
}
export default HomeComponent;
I managed to get this working by using setState an binding event to the form
import React from "react";
import APIHandler from "../utils/APIHandler";
import { Link } from "react-router-dom";
import AutoCompleteCustomer from "../components/AutoCompleteCustomer";
class HomeComponent extends React.Component {
constructor(props) {
super(props);
this.formSubmit = this.formSubmit.bind(this);
this.updateKgs = this.updateKgs.bind(this);
this.updatePackaging = this.updatePackaging.bind(this);
this.updateDiscount = this.updateDiscount.bind(this);
this.updateTransport = this.updateTransport.bind(this);
this.updatePrice = this.updatePrice.bind(this);
this.formRef = React.createRef();
}
state = {
errorRes: false,
errorMessage: "",
btnMessage: 0,
sendData: false,
farmerlist: [],
kgs: "",
price: "",
packaging: "",
discount: "",
transport: "",
amount: "",
customersDetails: [
{
id: 0,
phone: "",
name: "",
customer_id: "",
},
],
dataLoaded: false,
};
async formSubmit(event) {
event.preventDefault();
this.setState({ btnMessage: 1 });
var apiHandler = new APIHandler();
var response = await apiHandler.saveOrdersData(
event.target.phone.value,
event.target.name.value,
event.target.customer_id.value,
event.target.town.value,
event.target.region.value,
event.target.kgs.value,
event.target.packaging.value,
event.target.discount.value,
event.target.transport.value,
event.target.comment.value,
event.target.farmer_id.value,
event.target.rice_type.value,
event.target.price.value,
event.target.amount.value,
);
console.log(response);
this.setState({ btnMessage: 0 });
this.setState({ errorRes: response.data.error });
this.setState({ errorMessage: response.data.message });
this.setState({ sendData: true });
this.formRef.current.reset();
}
//This Method Work When Our Page is Ready
componentDidMount() {
this.LoadFarmer();
}
async LoadFarmer() {
var apihandler = new APIHandler();
var farmerdata = await apihandler.fetchFarmerOnly();
this.setState({ farmerlist: farmerdata.data });
}
showDataInInputs = (index, item) => {
console.log(index);
console.log(item);
this.state.customersDetails[index].id = item.id;
this.state.customersDetails[index].phone = item.phone;
this.state.customersDetails[index].name = item.name;
this.state.customersDetails[index].customer_id = item.id;
this.setState({})
}
updateKgs = (event) => {
this.setState({
kgs: event.target.value
});
}
updatePackaging = (event) => {
this.setState({
packaging: event.target.value
});
console.log(this.state.packaging)
}
updateDiscount = (event) => {
this.setState({
discount: event.target.value
});
}
updateTransport = (event) => {
this.setState({
transport: event.target.value
});
}
updatePrice = (event) => {
this.setState({
price: event.target.value
});
}
updateAmount = () => {
this.setState({
amount: (Number(this.state.kgs) * Number(this.state.price)) + Number(this.state.packaging) + Number(this.state.transport) - Number(this.state.discount)
});
}
render() {
return (
<section className="content">
<div className="container-fluid">
<div className="block-header">
<h2>ADD ORDERS & CUSTOMERS</h2>
</div>
<div className="row clearfix">
<div className="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div className="card">
<div className="header">
<h2>Add Order</h2>
<ul className="header-dropdown m-r--5">
<Link to={"/addcustomer"} className="toggled waves-effect waves-block">
<button className="btn btn-primary m-r-15 waves-effect">
Add Customer
</button>
</Link>
</ul>
</div>
<div className="body">
<form onSubmit={this.formSubmit} ref={this.formRef}>
{this.state.customersDetails.map((item, index) => (
<div className="row" key={index}>
<div className="col-lg-6">
<label htmlFor="email_address">
Phone No.{" "}
</label>
<div className="form-group">
<div className="form-line">
<AutoCompleteCustomer
itemPostion={index}
showDataInInputs={this.showDataInInputs}
/>
</div>
</div>
</div>
<div className="col-lg-5">
<label htmlFor="email_address">Customer Name</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="name"
name="name"
className="form-control"
placeholder="Enter Customer Name"
defaultValue={item.name}
/>
</div>
</div>
</div>
<div className="col-sm-1">
<label htmlFor="email_address">No</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="customer_id"
name="customer_id"
className="form-control"
placeholder=""
value={item.customer_id}
/>
</div>
</div>
</div>
</div>
))}
<div className="row">
<div className="col-lg-4">
<label htmlFor="email_address">Town</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="town"
name="town"
className="form-control"
placeholder="Enter Customer Town"
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Region</label>
<div className="form-group">
<div className="form-line">
<select id="region" name="region" className="form-control show-tick">
<option value="1">NAIROBI</option>
<option value="2">NYANZA</option>
<option value="3">CENTRAL</option>
<option value="4">COAST</option>
<option value="5">EASTERN</option>
<option value="6">NORTH EASTERN</option>
<option value="7">WESTERN</option>
<option value="8">RIFT VALLEY</option>
</select>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Kgs : </label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="kgs"
name="kgs"
className="form-control"
placeholder="Enter Quantity."
defaultValue={this.state.kgs}
onChange={this.updateKgs}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Packaging</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="packaging"
name="packaging"
className="form-control"
placeholder="Enter Amount"
defaultValue={this.state.packaging}
onChange={this.updatePackaging}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Discount.</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="discount"
name="discount"
className="form-control"
placeholder="Enter Discount."
defaultValue={this.state.discount}
onChange={this.updateDiscount}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Transport</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="transport"
name="transport"
className="form-control"
placeholder="Enter Transport."
defaultValue={this.state.transport}
onChange={this.updateTransport}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Comment</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="comment"
name="comment"
className="form-control"
placeholder="Enter Comment"
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Farmer Name</label>
<div className="form-group">
<select className="form-control show-tick"
id="farmer_id"
name="farmer_id"
>
{this.state.farmerlist.map((item) => (
<option key={item.id} value={item.id}>
{item.name}
</option>
))}
</select>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Rice Type</label>
<div className="form-group">
<div className="form-line">
<select id="rice_type" name="rice_type" className="form-control show-tick">
<option value="1">Pishori</option>
<option value="2">Komboka</option>
</select>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Price per Kg</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="price"
name="price"
className="form-control"
placeholder="Enter Price"
defaultValue={this.state.price}
onChange={this.updatePrice}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Amount</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="amount"
name="amount"
className="form-control"
placeholder="Enter Amount"
defaultValue={this.state.amount}
onClick={this.updateAmount}
/>
</div>
</div>
</div>
</div>
<br />
<button
type="submit"
className="btn btn-success m-t-15 waves-effect "
disabled={this.state.btnMessage === 0 ? false : true}
>
{this.state.btnMessage === 0
? "Add Order"
: "Adding Order Please Wait.."}
</button>
<br />
{this.state.errorRes === false &&
this.state.sendData === true ? (
<div className="alert alert-success">
<strong>Success!</strong> {this.state.errorMessage}.
<Link to="/orders" className="btn btn-info">View Orders</Link>
</div>
) : (
""
)}
{this.state.errorRes === true &&
this.state.sendData === true ? (
<div className="alert alert-danger">
<strong>Failed!</strong>
{this.state.errorMessage}.
</div>
) : (
""
)}
</form>
</div>
</div>
</div>
</div>
</div>
</section>
);
}
}
export default HomeComponent;
Hope this helpful to anyone facing a similar problem..

How can I resolve this React Modal Problem?

I am using react and I am a beginner in React. I am facing a problem while using React Modal.
It looks like modal is working but something is stopping it from working when I click on the button which opens Modal then this happens => The screen just blinks , The Modal opens and closes suddenly. I am using React useState Hook. No errors are reflected by the compiler in this code.
Here is my code :
import React from 'react'
import { useState } from 'react';
import Modal from 'react-modal'
import '../CSS/LoginSignup.css'
const LoginSignup = () => {
const [modalIsOpen , setIsOpen] = useState(false);
function openModal() {
setIsOpen(true);
}
function closeModal() {
setIsOpen(false);
}
function afterOpenModal() {
if(!closeModal){
setIsOpen(true);
}
}
return (
<>
<div>
<div className="mainContainer">
<div className="maincontrol">
<div className="tagline">
<h1>Chat Free</h1>
<span><p>Connect with peoples and chat the way you like.</p></span>
</div>
<div className="login">
<form className="form">
<input type="text" id="login" className="inp1" name="login" placeholder="Email address or phone number" />
<input id="password" type="password" className="inp1" name="login" placeholder="Password" />
<button type="submit" className="btn" value="Log In">Log In</button>
Forgotten password?
<button type="SignUp" className="btn1" value="Sign Up" name="signUp" onClick={openModal}>Sign Up</button>
<Modal isOpen={modalIsOpen}
onAfterOpen={afterOpenModal}
onRequestClose={closeModal}
>
<div className="modal">
<div className="modal-content">
<h2>Sign Up!</h2>
<span className="close" onClick={closeModal} >×</span>
<form className='formsignup'>
<div className="fullname">
<div className="firtname">
<input type="text" placeholder="First Name" id="firstname" />
</div>
<div className="surname">
<input type="text" placeholder="Last Name" id="lastname" />
</div>
</div>
<div className="emailphone">
<input type="text" placeholder="Email or phone number" id="ephone"/>
</div>
<div className="password">
<input type="password" placeholder="Enter password" id="password"/>
</div>
<div className="dobmain">
<div className="date">
<label htmlFor="dob">Date of birth</label>
<input type="number" placeholder="Date" id="date"/>
</div>
<div className="month">
<input type="text" placeholder="Month" id="month"/>
</div>
<div className="year">
<input type="number" placeholder="Year" id="year"/>
</div>
</div>
<div className="gender">
<div className="male">
<label htmlFor="">Male</label>
<input type="radio" name="gender" id="male" />
</div>
<div className="female">
<label htmlFor="">Female</label>
<input type="radio" name="gender" id="male" />
</div>
<div className="other">
<label htmlFor="">Other</label>
<input type="radio" name="gender" id="male" />
</div>
</div>
<div className="button">
<button type="Register" className="btnR" value="Register" name="register">Sign Up</button>
</div>
</form>
</div>
</div>
</Modal>
</form>
</div>
</div>
</div>
</div>
</>
)
}
export default LoginSignup
It is the content on my console:
[HMR] Waiting for update signal from WDS...
webpackHotDevClient.js:138 src\Component\LoginSignup.js
Line 33:33: The href attribute requires a valid value to be accessible. Provide a valid, navigable address as the href value. If you cannot provide a valid href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-is-valid.md jsx-a11y/anchor-is-valid
printWarnings # webpackHotDevClient.js:138

Does conditional fields with radio buttons in react forms work?

I am creating a form with 'occupation' field as radio button. There are two options for occupation-i.e. self employed and service. According to the choice the user makes for occupation, I am showing different fields of the form. I am using if-else for this conditional rendering. Code works well for if-part but doesn't work for the else-part. I am attaching my code for reference.
<div className="row">
<div className="col-md-3">
<input
type= "radio"
id= "fatherService"
name= "fatherOccupation"
value = "service"
checked={fatherOccupation === "service"}
onChange={handleFatherOccupation}
/>
<label htmlFor="fatherService">Service</label>
</div>
<div className="col-md-6">
<input
type= "radio"
id= "fatherSelfEmployed"
name= "fatherOccupation"
value = "selfEmployed"
checked={fatherOccupation === "selfEmployed"}
onChange={handleFatherOccupation}
/>
<label htmlFor="fatherSelfEmployed">Self Employed</label>
</div>
</div>
</div>
</div>
{fatherOccupation === "service" ? (
<div className="row">
<div className="col-md-6">
<label>Company Name:</label>
<input
type="text"
className="form-control p-2"
id="fatherCompanyName"
name="fatherCompanyName"
{...register("fatherCompanyName", {
required:"Please enter father's company name",
})}
/>
</div>
</div>
) : (
<div className="row">
<div className="col-md-6">
<label>Type of Business:</label>
<input
type="text"
className="form-control p-2"
id="fatherTypeOfBusiness"
name="fatherTypeOfBusiness"
{...register("fatherTypeOfBusiness", {
required:"Please enter father's type of business",
})}
/>
</div>
</div>
)}

TypeError: Cannot read property 'state' of undefined, even though already binded

im trying to print a state in my reactjs web page, i already bind the function just like the other answer says but it still gave me the same error, here is my code
export class Tambah extends React.Component{
constructor(){
super();
this.add = this.add.bind(this);
}
add(event){
this.setState({company: event.target.value})
}
}
function FormTambah(){
return(
<div className="konten container-sm">
<br></br><br></br>
<div className="tabel card rounded">
<div className="card-body">
<p className="head panel-body">Add User</p>
<br/><br/>
<form>
<p>Email*</p>
<input type="text" value={this.state.company} onChange={this.add} className="email form-control col-sm-6"/>
<br/>
<p>Full Name*</p>
<input type="text" className="email form-control col-sm-7" placeholder="Enter Fullname" onChange={this.FullName}></input>
<br/>
<div className="stat custom-control custom-switch">
<input type="checkbox" className="custom-control-input switch-lg" id="customSwitch1"/>
<label className="custom-control-label" for="customSwitch1">Active Status</label>
</div>
<br/>
<button type="submit" className="submit btn col-sm-1">Save</button>
</form>
</div>
</div>
</div>
)
}
the error happens right here :
<input type="text" value={this.state.company} onChange={this.add} className="email form-control col-sm-6"/>
i already bind the add method after i saw the other question but it still gave me the same error, thanks before, any help will be appreciated
state is available in class components not function components.
also beside react, what you're doing is not legal in JS, you're defining state in one class and try to use it in a different function that is not belong to that class.
what you want to do is move the code in FormTambah function to render function in the class component
export class Tambah extends React.Component{
constructor(){
super();
this.add = this.add.bind(this);
}
add(event){
this.setState({company: event.target.value})
}
render(){
return(
<div className="konten container-sm">
<br></br><br></br>
<div className="tabel card rounded">
<div className="card-body">
<p className="head panel-body">Add User</p>
<br/><br/>
<form>
<p>Email*</p>
<input type="text" value={this.state.company} onChange={this.add} className="email form-control col-sm-6"/>
<br/>
<p>Full Name*</p>
<input type="text" className="email form-control col-sm-7" placeholder="Enter Fullname" onChange={this.FullName}></input>
<br/>
<div className="stat custom-control custom-switch">
<input type="checkbox" className="custom-control-input switch-lg" id="customSwitch1"/>
<label className="custom-control-label" for="customSwitch1">Active Status</label>
</div>
<br/>
<button type="submit" className="submit btn col-sm-1">Save</button>
</form>
</div>
</div>
</div>
)
}
}
Put FormTambah into render:
export class Tambah extends React.Component {
constructor() {
super();
this.add = this.add.bind(this);
}
add(event) {
this.setState({ company: event.target.value });
}
render() {
return (
<div className="konten container-sm">
<br></br>
<br></br>
<div className="tabel card rounded">
<div className="card-body">
<p className="head panel-body">Add User</p>
<br />
<br />
<form>
<p>Email*</p>
<input
type="text"
value={this.state.company}
onChange={this.add}
className="email form-control col-sm-6"
/>
<br />
<p>Full Name*</p>
<input
type="text"
className="email form-control col-sm-7"
placeholder="Enter Fullname"
onChange={this.FullName}
></input>
<br />
<div className="stat custom-control custom-switch">
<input type="checkbox" className="custom-control-input switch-lg" id="customSwitch1" />
<label className="custom-control-label" htmlFor="customSwitch1">
Active Status
</label>
</div>
<br />
<button type="submit" className="submit btn col-sm-1">
Save
</button>
</form>
</div>
</div>
</div>
);
}
}

Setting Component State after Redux has Mapped Redux State to Props

I am trying to initialize a form with some user information using Redux Forms by pulling the information from my components state. I have a redux action in the componentDidMount method of my component that calls the action, retrieves the information, and then maps a 'profile' object from my store to the components props. The problem is, when I go to setState to update the profile info, it comes back as undefined. I have tried to use the componentWillRecieveProps to see if I can catch the updated 'Profile' props but it is still undefined. Whats the best way to update the component's state once 'this.props.profile' returns the users information?
Here is the component's code:
import React, { Component } from "react";
import { connect } from "react-redux";
import { Field, reduxForm } from "redux-form";
import { Link } from "react-router-dom";
import classnames from "classnames";
import * as actions from "../../actions";
class CreateProfile extends Component {
constructor(props) {
super(props);
this.state = {
showSocialMedia: true,
profile: {}
};
}
componentDidMount() {
this.props.getCurrentUserProfile();
}
// componentDidUpdate(prevProps, prevState) {
// if (prevProps.profile.profile !== this.props.profile.profile) {
// console.log(this.props.profile);
// }
// }
renderField(field) {
return (
<div className="form-group">
<input
className={classnames("form-control form-control-lg", {
"is-invalid": field.meta.touched && !field.meta.valid
})}
type={field.type}
placeholder={field.placeholder}
{...field.input}
/>
<small className="text-muted">{field.description}</small>
<div className="invalid">
{field.meta.touched && !field.meta.valid ? (
<div className="text-center">
<i className="far fa-edit" /> {field.meta.error}
</div>
) : (
""
)}
</div>
</div>
);
}
renderAlert() {
if (this.props.errors.message) {
return (
<div className="alert alert-danger error-message mt-4 text-center">
<h3>
<i className="fas fa-info-circle" />
</h3>
<h6 className="invalid">{this.props.errors.message}</h6>
</div>
);
}
}
renderSelectField(field) {
return (
<div className="form-group">
<select
className={classnames("form-control form-control-lg", {
"is-invalid": field.meta.touched && !field.meta.valid
})}
{...field.input}
>
<option value="" disabled>
* Select a Professional Status
</option>
<option value="Developer">Developer</option>
<option value="Junior Developer">Junior Developer</option>
<option value="Senior Developer">Senior Developer</option>
<option value="Manager">Manager</option>
<option value="Student or Learning">Student or Learning</option>
<option value="Instructor or Teacher">Instructor or Teacher</option>
<option value="Intern">Intern</option>
<option value="Other">Other</option>
</select>
<small className="text-muted">
Give us an idea of where you are at in your career
</small>
<div className="invalid">
{field.meta.touched && !field.meta.valid ? (
<div className="text-center">
<i className="far fa-edit" /> {field.meta.error}
</div>
) : (
""
)}
</div>
</div>
);
}
renderSocialMediaField(field) {
return (
<div className="form-group">
<div className="input-group-prepend">
<span className="input-group-text">
<i className={field.icon} />
</span>
<input
type={field.type}
className="form-control"
placeholder={field.placeholder}
icon={field.icon}
{...field.input}
/>
</div>
</div>
);
}
onSubmit(values) {
this.props.createNewUserProfile(values);
}
toggleHiddenSocialInputs(e) {
e.preventDefault();
this.setState({
showSocialMedia: !this.state.showSocialMedia
});
}
render() {
const { handleSubmit } = this.props;
const { profile } = this.props;
return (
<div className="container">
<div className="row">
<div className="col-md-8 m-auto">
<Link to="/dashboard" className="btn btn-light p-2 mt-2">
<i className="mr-1 fas fa-long-arrow-alt-left" /> Go Back
</Link>
<h5 className="display-4 pt-2 text-center font-weight-light">
Update Your Profile
</h5>
<p className="text-black-50 pt-3 font-weight-light">
* = required field
</p>
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
{this.renderAlert()}
<Field
name="handle"
type="text"
placeholder="* Profile handle"
component={this.renderField}
description="A unique handle for your profile URL - (Can't be changed later)"
/>
<Field name="status" component={this.renderSelectField} />
<Field
name="company"
type="text"
placeholder="Company"
component={this.renderField}
description="Can be your own or the one you work for"
/>
<Field
name="website"
type="text"
placeholder="Website"
component={this.renderField}
description="Could be your own or company website"
/>
<Field
name="location"
type="text"
placeholder="Location"
component={this.renderField}
description="Suggested format is: City, State"
/>
<Field
name="skills"
type="text"
placeholder=" Skills"
component={this.renderField}
description="Please use comma separated values (eg: HTML, CSS, Javascript, etc)"
/>
<Field
name="githubusername"
type="text"
placeholder="Github Username"
component={this.renderField}
description="If you want your latest repos and a Github link, include your username"
/>
<div className="form-control-group">
<Field
className="form-control form-control-lg"
name="bio"
placeholder="A short bio about yourself"
component="textarea"
/>
<small className="text-muted">
Tell us a little about yourself
</small>
</div>
<div className="row mt-2 pt-2">
<button
className="btn btn-outline-secondary m-auto"
onClick={this.toggleHiddenSocialInputs.bind(this)}
>
Add Social Network Links <i className=" ml-1 fas fa-users" />
</button>
</div>
{!this.state.showSocialMedia && (
<div className="mt-3">
<Field
name="facebook"
placeholder="Facebook profile URL"
icon="fab fa-facebook-square"
component={this.renderSocialMediaField}
/>
<Field
name="twitter"
placeholder="Twitter profile URL"
icon="fab fa-twitter-square"
component={this.renderSocialMediaField}
/>
<Field
name="linkedin"
placeholder="Linkedin profile URL"
icon="fab fa-linkedin"
component={this.renderSocialMediaField}
/>
<Field
name="youtube"
placeholder="Youtube profile URL"
icon="fab fa-youtube-square"
component={this.renderSocialMediaField}
/>
<Field
name="instagram"
placeholder="Instagram profile URL"
icon="fab fa-instagram"
component={this.renderSocialMediaField}
/>
</div>
)}
<button action="submit" className="btn btn-info btn-block mt-5">
Create Profile <i className=" ml-1 fas fa-user-alt" />
</button>
{this.renderAlert()}
</form>
</div>
</div>
</div>
);
}
}
function validate(values) {
const errors = {};
if (!values.handle) {
errors.handle = "Please enter a handle for your profile";
}
if (!values.status) {
errors.status = "Please select a status for your profile";
}
return errors;
}
const mapStateToProps = state => {
return {
errors: state.errors,
profile: state.profile
};
};
export default reduxForm({
validate,
form: "CreateProfile",
initialValues: {}
})(connect(mapStateToProps, actions)(CreateProfile));
First, I'm not sure why you want to attach profile to component state. But if this.props.profile is always undefined, then it sounds like you're failing to fetch the user profile or you're not updating the store correctly. I would need to see getCurrentUserProfile and your reducer.
Fwiw, I would dispatch a request for user information from a container and set initialValues to state.profile (if state.profile, is in fact, your initial user data).

Categories

Resources