I've tried using onSubmit on both the inputs and the submit button but I know that's wrong. and I've tried connecting the functions to the inputs. I've seen examples of people using https links to get it posted but I just want to be able to change the color and text when you click submit.
this.state = {
deftextcolor: "green",
text: "Color Me"
}
}
colorchanger(newcolor) {
this.setState({deftextcolor: newcolor})
}
textchanger(newtext) {
this.setState({text: newtext})
}
render() {
return (
<div className='colorer-wrapper'>
<h1 style={{color: this.state.deftextcolor}}>{this.state.text}</h1>
<input type="text"/>
<input type="text"/>
<button type="submit">Submit</button>
</div>
);
}
}
here some example:
const App =()=>{
const [state,setState] = React.useState({bgColor:"",textColor:"",color:"white",backgroundColor:"red"});
const handleChange = (e)=>{
const {target} = e
setState(current =>({...current,[target.name]:target.value}))
}
const onSubmit = (e)=>{
e.preventDefault();
if(state.bgColor.length>0 && state.textColor.length>0)
setState((current)=>({bgColor:"",textColor:"",color:current.textColor,backgroundColor:current.bgColor}))
}
return (<div><form style={{backgroundColor:state.backgroundColor,color:state.color}} onSubmit={onSubmit}>
<div>test style color</div>
<input type="text" name="bgColor" placeholder="background color" value={state.bgColor} onChange={handleChange}/>
<input type="text" name="textColor" value={state.textColor} onChange={handleChange} placeholder="text color"/>
<button type="submit">Apply style </button>
</form></div>)
}
ReactDOM.render(<App/>,document.getElementById("root"))
form{
width:100vw;
height:100vh
}
<script src="https://unpkg.com/react#16/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.production.min.js" crossorigin></script>
<div id="root"></div>
remenber you need to store event in variable because react update state asynchronously so the event will be gone.
Two places you can wire with onSubmit,
wire it with a button directly
<button onClick={onSubmit} />
wire it with form
<form onSubmit={onSubmit}>
<button type="submit" />
</form>
Your function needs to look like
const onSubmit = (e) => {
// do something. here
}
In your case, you also want to pass something into this function, so either calling handleSubmit directly or <button onClick={ e=> { colorchanger(color) } />
Like this:
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
deftextcolor: "green",
text: "Color Me",
defInput: '',
textInput: ''
}
}
handleChange = (e) => {
this.setState({[e.target.id]: e.target.value})
}
handleSubmit = () => {
this.setState((state) => ({
deftextcolor: state.defInput,
text: state.textInput,
defInput: '',
textInput: ''
}))
}
render() {
return (
<div className='colorer-wrapper'>
<h1 style={{color: this.state.deftextcolor}}>{this.state.text}</h1>
<input type="text" value={this.state.defInput} onChange={this.handleChange} id="defInput"/>
<input type="text" value={this.state.textInput} onChange={this.handleChange} id="textInput"/>
<button type="submit" onClick={this.handleSubmit}>Submit</button>
</div>
);
}
}
export default App
You can attach the same method to both inputs to update state input values, and then another method to the button that uses state input values to update your other state properties.
Related
I have this simple form in my App form. I learned that a button with type="reset" clears the inputs, but it isn't working here with React. Am I missing something?
import { useState } from "react";
export default function App() {
const [name, setName] = useState("");
return (
<form>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Name"
name="name"
/>
<button>Submit</button>
<button type="reset">Reset</button>
</form>
);
}
You must reset the state name with an empty string when the reset button is clicked.
export default function App() {
const [name, setName] = useState("");
const onClickReset = () => setName('');
return (
<form>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Name"
name="name"
/>
<button>Submit</button>
<button type="reset" onClick={onClickReset}>Reset</button>
</form>
);
}
import { useState } from "react";
export default function App() {
const [name, setName] = useState("");
return (
<form>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Name"
name="name"
/>
<button>Submit</button>
<button type="reset" onClick={() => setName('')}>Reset</button>
</form>
);
}
Use an object to maintain the initial state of the form and on RESET, update the state using the initial object.
Also, use event.preventDefault() to prevent the default action of the reset button.
const {useState} = React;
function App() {
const initState = {
name:''
};
const [name, setName] = useState(initState.name);
const onReset = (e)=>{
e.preventDefault();
setName(initState.name);
}
return (
<form>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Name"
name="name"
/>
<button>Submit</button>
<button type="reset" onClick={e=>onReset(e)}>Reset</button>
</form>
);
}
ReactDOM.createRoot(
document.getElementById("root")
).render(
<App />
)
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
The reason for this is that your input is now controlled by a state, if you want to clear the form by type='reset' try removing the value and onChange attributes in your input. but if you want to clear the state you can create a function that will handle this. here's a sample function for your reference.
function handleClear() {
setName('')
}
<button type="button" onClick={handleClear}>Reset</button>
I'm learning react and I'm super confused why this event handler is undefind ?
const Login = () => {
handleSubmit = (e) => {
console.log("Clicked");
e.preventDefault();
};
return (
<form onSubmit={this.handleSubmit}>
<input type="email" />
<input type="password" />
</form>
);
};
i get handleSubmit is not defined error and i have no idea
why is this happening ?
This seems to be a function component, let alone, using an arrow function. See this question for more details on that.
This means you don’t have access to the keyword “this”, which you’re using on your onSubmit!
i think you have forgot const and you don't need this keyword because you are using function component
const Login = () => {
const handleSubmit = (e) => {
console.log("Clicked");
e.preventDefault();
};
return (
<form onSubmit={handleSubmit}>
<input type="email" />
<input type="password" />
</form>
);
};
You're mixing up the two different ways to declare a React component.
Choose either:
Class component: which needs to extend the React.Component class, requires the return to be wrapped in render, and does need this to reference the class methods.
const { Component } = React;
class Example extends Component {
handleSubmit = (e) => {
e.preventDefault();
console.log("Clicked");
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="email" />
<input type="password" />
<button type="submit">Submit</button>
</form>
);
}
}
ReactDOM.render(
<Example />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Function component: which is just a function, doesn't require render, and doesn't require you to reference this to call the handler functions. In addition, function components allow you access to React hooks.
const { Component } = React;
function Example() {
function handleSubmit(e) {
e.preventDefault();
console.log("Clicked");
};
return (
<form onSubmit={handleSubmit}>
<input type="email" />
<input type="password" />
<button type="submit">Submit</button>
</form>
);
}
ReactDOM.render(
<Example />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
What I am trying to do is, upon clicking the Submit button, I want to grab the value that was typed into the input to then update the h1.
import React from "react";
function App() {
const [headingText, setHeadingText] = React.useState("");
function handleChange(event) {
setHeadingText(event.target.value);
}
function handleSubmit(event) {
alert(event.target);
}
return (
<div className="container">
<form onSubmit={handleSubmit}>
<h1>Hello {headingText}</h1>
<input
onChange={handleChange}
type="text"
placeholder="What's your name?"
value={headingText}
/>
<button type="submit">Submit</button>
</form>
</div>
);
}
export default App;
With the above code, so far I am able to update the h1 after every single keystroke that is entered into the input. But instead of that, I want to only update the h1 with the input value when I press the Submit button.
You'll need to use 2 useState's, one to hold the value of the input box, the other to hold the value of the header.
// import React from "react"; // not On StackOverflow
function App() {
const [headingTextBuffer, setHeadingTextBuffer] = React.useState("");
const [headingText, setHeadingText] = React.useState("");
function handleChange(event) {
setHeadingTextBuffer(event.target.value);
}
function handleSubmit(event) {
event.preventDefault();
setHeadingText(headingTextBuffer);
}
return (
<div className="container">
<form onSubmit={handleSubmit}>
<h1>Hello {headingText}</h1>
<input
onChange={handleChange}
type="text"
placeholder="What's your name?"
value={headingTextBuffer}
/>
<button type="submit">Submit</button>
</form>
</div>
);
}
// export default App; // not on StackOverflow
ReactDOM.render(<App />, document.querySelector("#root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>
One way you could do this is using an inputText state that is updated in your handleChange function.
Now when you submit in your submit function you can update the headingText state to be equal to the inputText which should update your h1 value.
You could put the result of each keystroke in the state in another field that is not displayed anywhere and on click put the value from that new field into the heading. Like this :
import React from "react";
function App() {
const [tempHeadingText, setTempHeadingText] = React.useState("");
const [headingText, setHeadingText] = React.useState("");
function handleChange(event) {
setTempHeadingText(event.target.value);
}
function handleSubmit(event) {
setHeadingText(tempHeadingText);
}
return (
<div className="container">
<form onSubmit={handleSubmit}>
<h1>Hello {headingText}</h1>
<input
onChange={handleChange}
type="text"
placeholder="What's your name?"
value={tempHeadingText}
/>
<button type="submit">Submit</button>
</form>
</div>
);
}
export default App;
I've made a form in ReactJS with one text input and when it submits I want to get its value and put it into a variable. But when I console.log() it returns as undefined. How do I fix this? Here is my code.
class App extends Component {
state = {
todoTitle: ""
};
render() {
return (
<div>
<center>
<form
onSubmit={(event) => {
event.preventDefault();
this.setState(todoTitle: event.target.value,);
console.log(this.state.todoTitle); // Returns "undefined"
}}
>
<input
type="text"
autocomplete="off"
class="form-control"
name="todoInput"
placeholder="Enter todo"
style={{ width: "400px", height: "50px" }}
/>
<input
type="submit"
value="Submit"
id="submitButton"
></input>
</form>
</center>
}
}
}
You need to either make a controlled input or useRef for un-controlled input for the React to keep track of your todoTitle state.
To make a controlled input, you will need to use onChange event and a value={this.state.todoTitle} property.
Also on your form, it is best to add an onSubmit event. There is however an option to set the submit on the form submit button also. In that case we need to use onClick={this.handleSubmit} as follows <input type="submit" value="Submit" id="submitButton" onClick={this.handleSubmit} />.
The below code will work for you:
class Form extends React.Component {
state = {
todoTitle: "",
};
handleSubmit = (e) => {
e.preventDefault();
console.log(this.state.todoTitle);
};
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<input
type="text"
autocomplete="off"
class="form-control"
name="todoInput"
placeholder="Enter todo"
style={{ width: "400px", height: "50px" }}
value={this.state.todoTitle}
onChange={(e) => this.setState({ todoTitle: e.target.value })}
/>
<input type="submit" value="Submit" id="submitButton" />
</form>
</div>
);
}
}
You can modify your app a bit to get the value on onChange of input textfield, and then store it in the array in case of below example:
export default class App extends React.Component {
state = {
todoTitle: "",
todoList: []
};
render() {
return (
<div>
<center>
<form
onSubmit={event => {
event.preventDefault();
this.setState(
{
todoList: [...this.state.todoList, this.state.todoTitle]
},
() => {
console.log(this.state.todoList);
}
);
}}
>
<input
type="text"
autocomplete="off"
class="form-control"
name="todoInput"
placeholder="Enter todo"
onChange={event => {
this.setState({ todoTitle: event.target.value });
console.log(event.target.value);
}}
style={{ width: "400px", height: "50px" }}
/>
<input type="submit" value="Submit" id="submitButton" />
</form>
</center>
</div>
);
}
}
Full app here: Stackblitz
There are a few other errors with your code, but I will just answer your question.
setState triggers a re-render, so your state isn't available to log until the next time it runs. You can just log what you put in setState.
console.log(event.target.value);
This question has more info.
setState doesn't update the state immediately
Also, you can do a callback.
this.setState({ todoTitle: event.target.value }, () =>
console.log(this.state.todoTitle)
);
Try this:
class App extends React.Component {
constructor(props) {
super(props);
this.state = { todoTitle: "" };
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
event.preventDefault();
this.setState({ todoTitle: event.target.value });
}
handleSubmit(event) {
event.preventDefault();
console.log(this.state.todoTitle);
}
render() {
return (
<div>
<center>
<form onSubmit={this.handleSubmit}>
<input
type="text"
autocomplete="off"
class="form-control"
name="todoInput"
placeholder="Enter todo"
style={{ width: "400px", height: "50px" }}
onChange={this.handleChange}
/>
<input type="submit" value="Submit" id="submitButton" />
</form>
</center>
</div>
);
}
}
This will change the state on input changes and then logs on submit the state. An alternative would be to just get the input element and its value via getElementById or something similar in React.
Your code was also not very well formatted and a lot of closing tags missed.
Read more here:
Get form data in ReactJS
In my component, I'm trying to call in an handleChange and handleSubmit functions of a component
If I render like the forms example,
<form onSubmit={this.handleSubmit}>
<input type="text" value={this.state.value} onChange={this.handleChange} placeholder="Enter new title"/>
<input type="submit" value="Submit" />
</form>
in onChange(), this won't be bound to the component, and I can't call this.setState, so I bind it with onChange={() => this.handleChange}.
for onSubmit(), I have the same binding problem, but when I bind it, the handler is not called, and the page is reloaded. What is the right way to bind to the component when submitting?
TIA
Full example:
class CbList extends React.Component {
constructor() {
super();
this.state = {
newTitle: '',
list: []
};
}
handleChange(event) {
this.setState(Object.assign({},
this.state,
{ newTitle: event.target.value }));
}
handleSubmit(event) {
this.addBlock(this.state.newTitle);
event.preventDefault();
return false;
}
render() {
return (
<div className="cb-list">
<div>
<form onSubmit={() => this.handleSubmit}>
<input type="text" value={this.state.value} onChange={() => this.handleChange}
placeholder="Enter new title"/>
<input type="submit" value="Submit" />
</form>
</div>
</div>
);
}
addBlock(title) {
let updatedList = this.state.list.concat({ title: title });
this.setState({ list: updatedList })
}
};
$(function() {
ReactDOM.render(<CbList/>, $('#home').get(0));
});
You forgot to invoke the functions:
onSubmit={()=>this.handleSubmit}
should be
onSubmit={()=>this.handleSubmit()}
Or, just pass a reference to the function:
onSubmit={this.handleSubmit}
but you'll need to bind your functions in the constructor (as show in the forms example link):
this.handleSubmit = this.handleSubmit.bind(this);
You need to bind you event handlers on constructor so you can use them among other events.
constructor(props) {
super(props)
this.handleSubmit = this.handleSubmit.bind(this)
this.handleChange = this.handleChange.bind(this)
}
Also, you don't need arrow function when using then as props.
<form onSubmit={this.handleSubmit}>
<input
type="text"
value={this.state.value}
onChange={this.handleChange}
placeholder="Enter new title"
/>
<input type="submit" value="Submit" />
</form>