How To Change A Class Component (input, Conditional) To Functional Component With UseState - Hook?
I'd like to change a working class component into a functional component. It's basically an input field that should:
1) Dynamically display/Mirror whatever you enter (see the h1 below the form) 2) Show "no data provided" if nothing entered
The error message says "Failed to compile ... unexpected use of "event""
import React, { useState } from "react"
function Exercise2() {
const [input, inputChange] = useState({firstName: ""})
const handleChange = () => {
inputChange({[event.target.name]: event.target.value});
}
let display
if (useState.firstName != "") {
display = useState.firstName
} else {
display = "no data provided!"
}
return (
<div>
<form>
<input
type="text"
name="firstName"
placeholder="Enter your data here"
value = "input.firstName"
onChange = "handleChange"
/>
</form>
<h1>{display}</h1>
</div>
)
}
export default Exercise2
Can someone point out what I am missing (without altering the code structure too much since I want to stick to my beginners logic). Thx
PS: this was my class component which worked perfectly and that I am trying to translate
class Exercise1 extends React.Component {
constructor() {
super()
this.state = {
firstName:""
}
this.handleChange = this.handleChange.bind(this)
}
handleChange (event) {
this.setState({
[event.target.name]: event.target.value
})
}
render() {
let display
if(this.state.firstName != "") {
display=this.state.firstName
} else {
display="no data provided!"
}
return (
<div>
<form>Input:
<input
type="text"
name="firstName"
placeholder = "Enter your data here!"
value={this.state.firstName}
onChange={this.handleChange}
/>
</form>
<h1>{display}</h1>
</div>
)
}
}
Answer
So, the key things are:
1) Not placing the variable/method names in curly braces
value={input.firstName}
onChange={handleChange}
2) Not including an event
arg in your handleChange
method:
const handleChange = (event) => {
Here I've corrected those problems and also changed how the display is being rendered to make it more "React-like".
const { useState } = React;
function Exercise2() {
// Here you're setting state and assigning an object to it with
// once property: `firstName`
const [ input, inputChange ] = useState({ firstName: '' });
const handleChange = (event) => {
// The click event has been passed in.
// `target` is the element that's been clicked. We're just grabbing the name and
// value from it. We're assigning the name `firstName` as a dynamic property key name
// (we wrap it in square braces), and assign the value to it. We do that because we want to
// update the `firstName` property in the state object.
// Because state is an object (and we might eventually have other properties in there
// that we want to keep when we update this value) we return an object containing all
// the properties of input, and the new dynamic property
inputChange({ ...input, [event.target.name]: event.target.value });
}
// `input` is an object with a firstName property.
// We can destructure the `firstName` property from the state to make
// it easier to work with
const { firstName } = input;
console.log(input)
let display;
if (firstName.length) {
display = firstName;
} else {
display = "no data provided!";
}
return (
<div>
<form>
<input
type="text"
name="firstName"
placeholder="Enter your data here"
value={firstName}
onChange={handleChange}
/>
</form>
<h1>{display}</h1>
</div>
);
}
ReactDOM.render(<Exercise2 />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"/>
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM