React, form refreshing issue, default behavior isn't prevented - reactjs

This question relates to React, form refreshing issue (sorry for duplication). But the thing is <form onSumbit={ validation } isn't triggered.
Here's short explanation what I'm trying to achieve as a result. I created a form where the user will enter email and text. When clicking on Submit button - data is sent via SmtpJS. Though, when I enter data - form reloads (form, not the whole page). I tried to control onSubmit event of the form, but it still reloads. Why?
import React, { Component, lazy, Suspense } from 'react';
import './App.css';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
// other components' imports
import { OnlineReception } from './components/OnlineReception/OnlineReception';
export default class App extends Component {
state = {
...
// feedback form
formData: {
host: "smtp.mailtrap.io",
recipient: "recipient#gmail.com", // email is an example here
sender: "",
text: "",
subject: "Feedback",
token: ""
}
}
// send email with data
// from Online Reception's
// component form
/*
sendEmail = () => {
window.Email.send({
Host : this.state.formData.host,
Username : "someUsername", // for local testing
Password : "somePassword", // for local testing
To : this.state.formData.recipient,
From : this.state.formData.sender,
Subject : this.state.formData.subject,
Body : `<html>${this.state.formData.text}</html>`
}).then(
message => alert(message)
)
};
*/
// changing sender & message input values
toggleChangeSender = async (event) => {
await this.setState({
...this.state,
formData: {
host: this.state.formData.host,
recipient: this.state.formData.recipient,
sender: event.target.value,
text: this.state.formData.text,
subject: this.state.formData.subject,
token: this.state.formData.token
}
});
console.log("sender - ", this.state.formData.sender);
}
toggleChangeText = async (event) => {
await this.setState({
...this.state,
formData: {
host: this.state.formData.host,
recipient: this.state.formData.recipient,
sender: this.state.formData.sender,
text: event.target.value,
subject: this.state.formData.subject,
token: this.state.formData.token
}
});
console.log("text - ", this.state.formData.text);
}
render() {
return (
<BrowserRouter>
<div className="App">
...
<Switch>
...
<Route path="/online-reception/" component={
() =>
<OnlineReception
formData={ this.state.formData }
onChangeSenderData={ this.toggleChangeSender }
onChangeTextData={ this.toggleChangeText }
/>
} />
</Switch>
</div>
</BrowserRouter>
);
}
}
OnlineReception component with a form
import React from 'react';
import './css/OnlineReception.css';
export const OnlineReception = (props) => {
let { formData } = { ...props };
const validation = (e) => {
e.preventDefault();
console.log("validation called");
console.log("formData - ", formData);
};
return (
<div className="OnlineReception">
<h3 className="title">
Feedback
</h3>
<form className="feedback"
onSubmit={ validation }
>
<div className="wrapper">
<label>
Email
</label>
<input
type="email"
name="replyto"
className="field"
placeholder="Example: yourname#gmail.com"
autoComplete="off"
value={ formData.sender }
onChange={ props.onChangeSenderData }
/>
<label>
Message
</label>
<textarea
name="message"
className="field text-body"
placeholder="Text here"
value={ formData.text }
onChange={ props.onChangeTextData }
/>
<div className="buttonBox">
<button className="submit"
type="submit"
>
Submit
</button>
</div>
</div>
</form>
</div>
)
};

It seem to be working for me. Though, I just tried it without React Router, just a straight component and it worked fine. I think your issue is you are using the component prop instead of the render prop.
try <Route path="/online-reception/" render={ ...

Related

React V6 Not able to redirect to another page with button click with class component [duplicate]

I want to perform navigation on certain user actions, say onSubmit of a button. suppose a user clicks on the Add contact button I want react-router to redirect in "/" which is the home page. At the moment I am facing this problem--> TypeError: Cannot read properties of undefined (reading 'push'). As a beginner, I would really appreciate experts' help.
AddContacts.js
import React, { Component } from "react";
import { Consumer } from "../../context";
import TextInputGroup from "../layout/TextInputGroup";
import { v4 as uuidv4 } from "uuid";
import { useNavigate } from "react-router-dom";
class AddContacts extends Component {
state = {
name: "",
email: "",
phone: "",
errors: {},
};
onSubmit = (dispatch, e) => {
e.preventDefault();
const { name, email, phone } = this.state;
//Check for errors
if (name === "") {
this.setState({ errors: { name: "Name is required" } });
return;
}
if (email === "") {
this.setState({ errors: { email: "Email is required" } });
return;
}
if (phone === "") {
this.setState({ errors: { phone: "Phone is required" } });
return;
}
const newContact = {
id: uuidv4(),
name,
email,
phone,
};
dispatch({ type: "ADD_CONTACT", payload: newContact });
this.setState({
name: "",
email: "",
phone: "",
errors: {},
});
this.props.navigate.push("/");
};
onChange = (e) => this.setState({ [e.target.name]: e.target.value });
render() {
const { name, email, phone, errors } = this.state;
return (
<Consumer>
{(value) => {
const { dispatch } = value;
return (
<div className="card mb-3">
<div className="card-header">Add Contacts</div>
<div className="card-body">
<form onSubmit={this.onSubmit.bind(this, dispatch)}>
<TextInputGroup
label="Name"
name="name"
placeholder="Enter Name..."
value={name}
onChange={this.onChange}
error={errors.name}
/>
<TextInputGroup
label="Email"
name="email"
type="email"
placeholder="Enter Email..."
value={email}
onChange={this.onChange}
error={errors.email}
/>
<TextInputGroup
label="Phone"
name="phone"
placeholder="Enter Phone..."
value={phone}
onChange={this.onChange}
error={errors.phone}
/>
<input
type="submit"
value="Add Contact"
className="btn btn-light btn-block mt-3"
/>
</form>
</div>
</div>
);
}}
</Consumer>
);
}
}
export default AddContacts;
Here is the App.js file
import React, { Component } from "react";
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
import Contacts from "./components/contacts/Contacts";
import Header from "./components/layout/Header";
import AddContacts from "./components/contacts/AddContacts";
import About from "./components/pages/About";
import { Provider } from "./context";
import "bootstrap/dist/css/bootstrap.min.css";
import "./App.css";
function App() {
return (
<Provider>
<BrowserRouter>
<div className="App">
<Header branding="Contact manager" />
<div className="container">
<Routes>
<Route path="/" element={<Contacts />} />{" "}
<Route path="/contact/add/*" element={<AddContacts />} />{" "}
<Route path="about/*" element={<About />} />{" "}
</Routes>{" "}
</div>{" "}
</div>{" "}
</BrowserRouter>{" "}
</Provider>
);
}
export default App;
Issue
TypeError: Cannot read properties of undefined (reading 'push')
This is cause by you attempting to navigate from a navigate prop that doesn't exist, it's undefined.
this.props.navigate.push("/");
The useNavigate hook is only compatible with function components, so of you want/need to use navigate with a class component you must either convert AddContacts to a function component, or roll your own custom withRouter Higher Order Component to inject the "route props" like the withRouter HOC from react-router-dom v5.x did.
Solution
I won't cover converting a class component to function component. Here's an example custom withRouter HOC:
const withRouter = WrappedComponent => props => {
const navigate = useNavigate();
// etc... other react-router-dom v6 hooks
return (
<WrappedComponent
{...props}
navigate={navigate}
// etc...
/>
);
};
And decorate the AddContacts component with the new HOC.
export default withRouter(AddContacts);
This will now pass a navigate prop (and any others you set up) to the decorated components and this.navigate will now be defined.
Additionally, the navigation API changed from v5 to v6, it's no longer the direct history object being used. navigate is a function instead of an object. To use you invoke the function and pass 1 or 2 arguments, the first is the target path, the second is an optional "options" object with replace and/or state key/values.
interface NavigateFunction {
(
to: To,
options?: { replace?: boolean; state?: State }
): void;
(delta: number): void;
}
To navigate now as follows:
this.props.navigate("/");

How to update props of child to child component

So im trying to pass some props from my login component to the payment component with the user's info, to do this I update as shown below:
import React, { Component } from 'react';
import Login from './login';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Pay from './payment';
export default class app extends Component {
constructor(props) {
super(props);
this.state = {
LoggedInState: false,
LoggedInUser: [],
SellingProduct: [],
Users: [],
generalproducts: []
}
}
render() {
return (
<BrowserRouter>
<NavBar logged={this.state.LoggedInUser} />
<div className="container-fluid">
<Routes>
<Route path='/' element={<HomePage products={this.generalproducts} />} />
<Route path='/shoppingcart' element={<ShopCart logged={this.state.LoggedInState} paymentHandle={this.onBuyFromCart} products={this.state.generalproducts} />} />
<Route path='/login' element={<Login onLogged={this.onLogInSuccesful} />} />
<Route path='/Payment' element={<Pay ProductInProcess={this.state.SellingProduct} user={this.state.LoggedInUser} />} />
<Route path='/Camera' element={<Cam />} />
<Route path='*' element={<Nomatch />} />
</Routes>
</div>
</BrowserRouter>
)
}
onBuyFromCart = (prod) => {
console.log('in');
this.setState({ SellingProduct: prod });
console.log('dada');
}
onLogInSuccesful = (userlogged) => {
this.setState({ LoggedInState: true, LoggedInUser: userlogged });
console.log('AppLoggedinState', this.state.LoggedInState);
console.log('AppLoggedinuser', this.state.LoggedInUser);
};
componentDidMount = async () => {
var response = await fetch("http://localhost:5000/products");
var ConvertedProducts = await response.json();
this.setState({ generalproducts: ConvertedProducts });
}
}
It works fine from login component to the parent component but when payment tab is displayed I get no values using props, for example:
import React, { Component } from "react";
import { Link } from "react-router-dom";
export default class Pay extends Component {
constructor(props) {
super(props);
this.state = {
productSaled: this.props.ProductInProcess,
info: [],
stored: false
};
}
render() {
return (
<button className="card p-3" onClick={() => { this.onStoredCardClick(); }}>
<div className="img-box">
<img src="https://www.freepnglogos.com/uploads/mastercard-png/file-mastercard-logo-svg-wikimedia-commons-4.png"
alt="" />
</div>
<div className="number">
<label className="fw-bold">{this.props.user.CreditCardnum}</label>
</div>
<div className="d-flex align-items-center justify-content-between">
<small><span className="fw-bold">Expiry date:</span><span>{this.props.user.CreditCardDate}</span></small>
<small><span className="fw-bold">Name:</span><span>{this.props.user.CreditCardName}</span></small>
</div>
</button>
);
}
onStoredCardClick = () => {
this.setState({ stored: true });
console.log('state ', this.state);
console.log(' props', this.props);
}
componentDidMount = () => {
console.log(this.state);
}
}
gives me nothing as seen here:payment info
And login component is:
import React, { Component } from "react";
export default class Login extends Component {
constructor(props) {
super(props);
this.state = { email: "", password: "", message: "" };
}
render() {
return (
<div>
<h4 className="m-1 p-2 border-bottom">Login</h4>
{/* Email starts */}
<div className="form-group form-row">
<label className="col-lg-4">Email:</label>
<input
type="text"
className="form-control"
value={this.state.email}
onChange={(event) => {
this.setState({ email: event.target.value });
}}
/>
</div>
{/* Email ends */}
{/* Password starts */}
<div className="form-group form-row">
<label className="col-lg-4">Password:</label>
<input
type="password"
className="form-control"
value={this.state.password}
onChange={(event) => {
this.setState({ password: event.target.value });
}}
/>
</div>
{/* Password ends */}
<div className="text-right">
{this.state.message}
<button className="btn btn-primary m-1" onClick={this.onLoginClick}>
Login
</button>
</div>
</div>
);
} //end of render
//Executes when the user clicks on Login
onLoginClick = async () => {
var response = await fetch(
`http://localhost:5000/users?id=${this.state.email}&password=${this.state.password}`,
{ method: "GET" }
);
var body = await response.json();
if (body.length > 0) {
//success
var response = await fetch(
`http://localhost:5000/users/${this.state.email}`,
{ method: "GET" }
);
var body = await response.json();
console.log(body);
this.setState({
message: <span className="text-success">Successfully Logged-in</span>,
});
this.props.onLogged(body);
//window.location = '\payment';
} else {
//error
this.setState({
message: (
<span className="text-danger">Invalid login, please try again</span>
),
});
}
};
}
this is the console log form AppState
And this is the console log from Payment
Well, after a couple months I found out that when using window.locaionthe page will refresh al previous values for the props given, therefore, nothing will arrive to the component being loaded. To prevent this I changed to the usage of useNavigate and the hook useContext this solved the shortage of arriving information to the other children components. I am not good with the terminology of react yet so excuse for it.
The log in component now look like this (please focus on the useNavigate and useContext as for it is what solved my error):
import React, { Component, useState, useContext } from "react";
import { UserContext } from "./UserContext";
import { useNavigate } from "react-router-dom";
export default function Login(props) {
const [State, setState] = useState({
Email: "",
password: "",
message: "",
});
const history = useNavigate();
const [GeneralState, setGeneralState] = useContext(UserContext);
let onLoginClick = async () => {
const response1 = await fetch(
`http://localhost:5000/users?id=${State.Email}&password=${State.password}`,
{ method: "GET" }
);
const body1 = await response1.json();
if (body1.length > 0) {
//success
const response = await fetch(
`http://localhost:5000/users/${State.Email}`,
{ method: "GET" }
);
const body = await response.json();
setState({
message: <span className="text-success">Successfully Logged-in</span>,
});
setGeneralState({
...GeneralState,
LoggedInState: true,
LoggedInUser: body,
})
history("/shoppingcart", { replace: true });
} else {
//error
setState({
message: (
<span className="text-danger">Invalid login, please try again</span>
),
});
}
};
return (
<div>
<h4 className="m-1 p-2 border-bottom">Login</h4>
{/* Email starts */}
<div className="form-group form-row">
<label className="col-lg-4">Email:</label>
<input
type="text"
className="form-control"
value={State.Email}
onChange={(event) => {
setState({ ...State, Email: event.target.value });
}}
/>
</div>
{/* Email ends */}
{/* password starts */}
<div className="form-group form-row">
<label className="col-lg-4">password:</label>
<input
type="password"
className="form-control"
value={State.password}
onChange={(event) => {
setState({ ...State, password: event.target.value });
// console.log(GeneralState)
}}
/>
</div>
{/* password ends */}
<div> <a href="/register" style={{ fontSize: 12 }}>No tienes cuenta? Registrate</a></div>
<div className="text-right">
{State.message}
<button className="btn btn-primary m-1" onClick={onLoginClick}>
Login
</button>
</div>
</div>
);
//Executes when the user clicks on Login
}
And the UserContext component, from where useContext takes the info, is this one:
import { createContext } from "react";
export const UserContext = createContext();
As for the other components like app component, shown in the question statement at the start of this thread, it is necessary to also add the useContext statements so that your whole project will work under the same context.

Reactjs - Login redirect but has Invalid Hook Call

My goal here is to redirect the login to dashboard after a successful response. However, I am getting
Error: Invalid hook call. Hooks can only be called inside of the body
of a function component. This could happen for one of the following
reasons:
I have imported useHistory from react-router-dom but cannot initialize it inside the body of the LoginPage. All I would like to achieve is to redirect to the dashboard page.
Login.js
import React, { Component } from 'react';
import { useHistory } from "react-router-dom";
export class Login extends Component {
static displayName = Login.name;
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
errors: {},
submitted: false
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
const { name, value } = e.target;
this.setState({ [name]: value });
}
handleSubmit(e) {
e.preventDefault();
//const history = useHistory();
this.setState({ submitted: true });
const { username, password } = this.state;
const { dispatch } = this.props;
let errors = {};
if (username == "admin" && password == "admin") {
//history.push('/dashboard');
console.log("Logged-in");
} else {
errors["credentials"] = "You have entered the wrong username or password.";
}
this.setState({
errors: errors
});
}
render = () => {
const history = useHistory();
const { loggingIn } = this.props;
const { username, password, submitted } = this.state;
return (
<div className="col-md-6 col-md-offset-3">
<h1>Login</h1>
<form name="form" onSubmit={this.handleSubmit}>
<div className={'form-group' + (submitted && !username ? 'has-error' : '')}>
<label>Username</label>
<input type="text" className="form-control" name="username" value={username} onChange={this.handleChange} placeholder="Username" />
{submitted && !username &&
<div className="error">Username is required</div>
}
</div>
<div className="form-group mt-3">
<label>Password</label>
<input type="password" className="form-control" name="password" value={password} onChange={this.handleChange} placeholder="Password" />
{submitted && !password &&
<div className="error">Password is required</div>
}
</div>
<div className="error">{this.state.errors.credentials}</div>
<div className="form-group mt-3">
<button className="btn btn-primary">Login</button>
</div>
</form>
</div>
);
}
}
React hooks aren't compatible with class-components, they can only be used by function components and custom React hooks, so you will need to access the history object another way.
If Login component is directly rendered by a Route component, i.e. <Route path="......" component={Login} /> then route props are already injected as props. You can safely access this.props.history and issue the imperative navigation.
handleSubmit(e) {
e.preventDefault();
this.setState({ submitted: true });
const { username, password } = this.state;
const { dispatch, history } = this.props; // <-- destructure
const errors = {};
if (username == "admin" && password == "admin") {
history.push('/dashboard'); // <-- navigate
} else {
errors["credentials"] = "You have entered the wrong username or password.";
this.setState({ errors }); // <-- move error state update here
}
}
Use the withRouter Higher Order Component to inject the route props, then access the history object as above.
import { withRouter } from 'react-router-dom';
...
export default withRouter(Login);
Don't forget to update and default import Login here it's rendered.
You can't use hooks in a Class Component, it can only be used in just functional Components. that's why you are getting this error.
you can redirect in Class Components by using
import { Redirect } from 'react-router-dom'
<Redirect to="/dashboard" />
You cannot use hooks like 'useHistory' in class based component, so change your handleSubmit function to something like this:
handleSubmit(e) {
e.preventDefault();
//const history = useHistory();
this.setState({ submitted: true });
const { username, password } = this.state;
const { dispatch } = this.props;
let errors = {};
if (username == "admin" && password == "admin") {
props.history.push('/dashboard');
console.log("Logged-in");
} else {
errors["credentials"] = "You have entered the wrong username or password.";
}
this.setState({
errors: errors
});
}
You can use props.history.push
when you have used a class component you cant use hook in react so you need to used another thing like if the component that is used inside the route is in the browser route you can this.props.history.push('your location')if not found like that
<Route to="login" component={login}/>
else you can use this shape <Redirect to="/dashboard" />

React Hook: Why is my alert different from the props received?

I'm new to React hooks. I'm trying to display a props received from another component in a small alert.
import React, { Fragment } from "react";
import { useAlert } from "react-alert";
const Alert = props => {
const alert = useAlert();
console.log("<< # Alert props.message", props.message); // Diplays "deputy saved"
return (
<Fragment>
<button
className="btn btn-outline-secondary"
onClick={() => {
alert.show(props.message); // Displays the previous props received. Not the one from the console log above.
}}
>
Ajouter
</button>
</Fragment>
);
};
export default Alert;
Here is the component in which the alert is rendered. The message is setstate after being fetched by my Api file. This message contains the res.json from my Node server. For example "deputy created" or "this deputy already exists". The message is then sent to the alert component via an attribute and received as a props.
// AddParty Component
import React from "react";
import { Form, Text, TextArea } from "informed";
import styled from "styled-components";
import Alert from "../../core/admin/Alert";
import "react-datepicker/dist/react-datepicker.css";
import Api from "../../../utils/Api";
class AddParty extends React.Component {
constructor(props) {
super(props);
this.state = {
image: {},
message: ""
};
this.handleChange = this.handleChange.bind(this);
}
handleChange({ name, value }) {
this.setState({
[name]: value
});
}
async onSubmit(formState) {
console.info("formState", formState);
const { image } = this.state;
const newParty = new FormData();
newParty.append("image", image, image.name);
newParty.append("data", JSON.stringify(formState));
const message = await Api.addParty(newParty);
console.log("message :", message);
this.setState({
message
});
}
render() {
const { message, isSubmitted } = this.state;
console.log("message", message);
return (
<Container className="container">
<Form onSubmit={formState => this.onSubmit(formState)}>
<Label>
Nom du parti:
<Text
field="name"
type="text"
className="form-control form-control-sm"
/>
</Label>
<Label>
Description :
<TextArea
field="description"
className="form-control form-control-sm"
/>
</Label>
<Label>
Photo:
<input
type="file"
onChange={event =>
this.handleChange({
name: "image",
value: event.target.files[0]
})
}
/>
</Label>
<Alert
type="submit"
className="btn btn-outline-secondary"
message={message}
/>
</Form>
</Container>
);
}
}
export default AddParty;
I don't understand why the alert displayed is always the one from the previous props received, not the one showing in the console.log
I solved my problem using another react alert module called react-toastify. https://www.npmjs.com/package/react-toastify
Thanks you to all that helped me

Enzyme: Value returns undefined when simulating onSubmit

I'm trying to simulate the way the form was submitted. So to summarize when the user types in the textarea 'field, the component must be updated, then the user presses the submit button and the component is updated again. I expect that the value filled in the textarea will be empty after the user successfully submit. But unexpectedly the returned value is undefined.
CommentBox.js
import React from 'react';
class CommentBox extends React.Component {
state = {
comment: ''
}
handleChange = event => {
this.setState({
comment: event.target.value
})
}
handleSubmit = event => {
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<h4>Add a comment</h4>
<textarea onChange={this.handleChange} value={this.state.comment} />
<div>
<button>Submit Comment</button>
</div>
</form>
)
}
}
export default CommentBox;
CommentBox.text.js
import React from 'react';
import { mount } from 'enzyme';
import CommentBox from 'components/CommentBox';
let wrapped;
beforeEach(() => {
wrapped = mount(<CommentBox />);
})
afterEach(() => {
wrapped.unmount();
})
it('when form is submitted, text area gets emptied', () => {
wrapped.find('textarea').simulate('change', {
target: { value: 'new comment' }
})
wrapped.update();
wrapped.find('form').simulate('submit', {
preventDefault: () => {}
});
wrapped.update();
expect(wrapped.find('textarea').prop('value')).toEqual('');
})
I expect the output will be passed but the actual output is value returns undefined so test is failed.
I don't see anything that would make the test fail... other than not including this.setState({ comment: "" }); in the handleSubmit callback.
If you utilize state, then you have to manually reset it (or if the component unmounts, then it loses state automatically). React works by manipulating a virtual DOM. Then, you utilize state to manipulate the elements within this virtual DOM. Since you're preventing a page refresh (e.preventDefault) the state persists as intended.
Working example (click the Tests tab -- next to the Browser tab -- to run the test):
components/CommentBox
import React, { Component } from "react";
class CommentBox extends Component {
state = { comment: "" };
handleChange = ({ target: { value } }) => {
this.setState({ comment: value });
};
handleSubmit = e => {
e.preventDefault();
console.log("submitted comment: ", this.state.comment);
this.setState({ comment: "" });
};
render = () => (
<div className="app">
<form onSubmit={this.handleSubmit}>
<h4>Add a comment</h4>
<textarea
className="uk-textarea"
onChange={this.handleChange}
value={this.state.comment}
/>
<div className="button-container">
<button type="submit" className="uk-button uk-button-primary">
Submit Comment
</button>
</div>
</form>
</div>
);
}
export default CommentBox;
components/CommentBox/__tests__/CommentBox.test.js
import React from "react";
import { mount } from "enzyme";
import CommentBox from "../index";
describe("Comment Box", () => {
let wrapper;
beforeEach(() => {
wrapper = mount(<CommentBox />);
});
afterEach(() => {
wrapper.unmount();
});
it("when form is submitted, text area gets emptied", () => {
wrapper.find("textarea").simulate("change", {
target: { value: "new comment" }
});
expect(wrapper.find("textarea").prop("value")).toEqual("new comment");
wrapper.find("form").simulate("submit", {
preventDefault: () => {}
});
expect(wrapper.find("textarea").prop("value")).toEqual("");
});
});
handleChange = (e) => {
if(e.keyCode == 13 && e.shiftKey == false) {
e.preventDefault();
this.myFormRef.submit();
}
}
render() {
return (
<form ref={el => this.myFormRef = el} >
<h4>Add a comment</h4>
<textarea onKeyDown={this.handleChange} value={this.state.comment}
/>
<div>
<button type="submit">Submit Comment</button>
</div>
</form>
);
}
you can do like this on enter
You may try this:
import React from 'react';
class CommentBox extends React.Component {
//adding initVal for setting initial value in textbox
// and playing with it until the form submits
state = {
comment: '',
initVal: ''
}
handleChange = event => {
//on change in textfield, updating initVal with the typed text
this.setState({
initVal: event.target.value
})
}
handleSubmit = event => {
//finally on submission comment is updated with entered value
//which you may use it for further operations
//and initVal is set back to empty '' for setting textfield value as empty
//field
this.setState({
comment: this.state.initVal
initVal: ''
})
//event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<h4>Add a comment</h4>
//changes here
<textarea onChange={this.handleChange} value={this.state.initVal} />
<div>
<button>Submit Comment</button>
</div>
</form>
)
}
}
export default CommentBox;

Resources