Reputation: 39
I am new to learning react and I am having a tough time converting class components into functional components for understanding problems and analyzing . I want to use functional approach for understanding states and life cycle methods how that works in hooks concept .
How we can achieve this?
my code in class are
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
flag: false,
fields: [],
Namefield: { value: '', error: '' },
Emailfield: { value: '', error: '' },
Mobilefield: { value: '', error: '' },
tablerows: []
};
this.handleName = this.handleName.bind(this);
this.handleMobile = this.handleMobile.bind(this);
this.handleMail = this.handleMail.bind(this);
this.addRow = this.addRow.bind(this);
}
handleName(e) {
this.setState({
Namefield: {
value: e.target.value,
error: false
}
})
}
handleMobile(e) {
this.setState({
Mobilefield: {
value: e.target.value,
error: false
}
})
}
handleMail(e) {
this.setState({
Emailfield: {
value: e.target.value,
error: false
}
})
}
addRow(e) {
e.preventDefault();
var newdata = { name: this.state.Namefield.value, mobile: this.state.Mobilefield.value, mail: this.state.Emailfield.value }
// //take the existing state and concat the new data and set the state again
this.setState({ tablerows: this.state.tablerows.concat(newdata), flag: true });
const name1 = this.state.Namefield;
const mob1 = this.state.Mobilefield;
const mail1 = this.state.Emailfield;
if (name1.value !== "") {
const newName = [...this.state.fields, name1]
this.setState({
fields: newName,
Namefield: {
value: '',
error: ''
}
})
}
if (mob1.value !== "") {
const newMob = [...this.state.fields, mob1]
this.setState({
fields: newMob,
Mobilefield: {
value: '',
error: ''
}
})
}
if (mail1.value !== "") {
const newMail = [...this.state.fields, mail1]
this.setState({
fields: newMail,
Emailfield: {
value: '',
error: ''
}
})
}
}
deleteRow(passedID) {
let tablerows = [...this.state.tablerows]
tablerows.splice(passedID, 1)
this.setState({
tablerows: tablerows
})
}
editRow = (index, type, values) => {
const newState = this.state.tablerows.map((item, i) => {
if (i === index) {
return { ...item, [type]: values };
}
return item;
});
this.setState({
tablerows: newState
});
}
render() {
return (
<div className="App">
<header className="App-header">Sample CRUD Operations</header>
<form >
<input
type="text"
placeholder="Name"
value={this.state.Namefield.value}
onChange={this.handleName} /> <br />
<input
type="number"
placeholder="Mobile"
maxLength="10"
value={this.state.Mobilefield.value}
onChange={this.handleMobile} /> <br />
<input
type="email"
placeholder="Email"
value={this.state.Emailfield.value}
onChange={this.handleMail} /> <br />
<div>
<button onClick={this.addRow}>ADD</button>
</div>
</form>
{this.state.tablerows.length > 0 ?
<table style={{ "backgroundColor": "rgb(192, 217, 236)" }}>
<thead style={{ "backgroundColor": "rgb(73, 116, 201)", "color": "white" }}>
<tr style={{ "height": "50px" }}>
<th>Name</th>
<th>Mobile</th>
<th>Email</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{this.state.tablerows.map((row, index) =>
<tr key={index}>
<td> <input
type="text"
value={row.name}
onChange={(e) => this.editRow(index, "name", e.target.value)} /></td>
<td> <input
type="number"
maxLength="10"
value={row.mobile}
onChange={(e) => this.editRow(index, "mobile", e.target.value)} /></td>
<td> <input
type="email"
value={row.mail}
onChange={(e) => this.editRow(index, "mail", e.target.value)} /></td>
<td><button className="deleteBtn" onClick={() => this.deleteRow(index)}>-</button></td>
</tr>)}
</tbody>
</table> : ""}
</div>
);
}}
Upvotes: 3
Views: 19294
Reputation: 5854
You can follow the below code and continue rest of your code conversion.
import React from 'react';
function App() {
const [state, setState] = useState({
flag: false,
fields: [],
Namefield: { value: '', error: '' },
Emailfield: { value: '', error: '' },
Mobilefield: { value: '', error: '' },
tablerows: []
});
const addRow = (e) => {
e.preventDefault();
var newdata = { name: state.Namefield.value, mobile: state.Mobilefield.value, mail: state.Emailfield.value };
//take the existing state and concat the new data and set the state again
setState({ tablerows: state.tablerows.concat(newdata), flag: true });
const name1 = state.Namefield;
const mob1 = state.Mobilefield;
const mail1 = state.Emailfield;
if (name1.value !== "") {
const newName = [...state.fields, name1];
setState({
fields: newName,
Namefield: {
value: '',
error: ''
}
});
}
if (mob1.value !== "") {
const newMob = [...state.fields, mob1];
setState({
fields: newMob,
Mobilefield: {
value: '',
error: ''
}
});
}
if (mail1.value !== "") {
const newMail = [state.fields, mail1];
setState({
fields: newMail,
Emailfield: {
value: '',
error: ''
}
});
}
}
const handleName = (e) => {
setState({
...state,
Namefield: {
value: e.target.value,
error: false
}
})
};
return (
<div className="App">
....
</div>
);
};
export default App;
Here are the steps:
- use function instead of class
- remove the constructor
- remove the render() method, keep the return
- add const before all methods
- remove this.state throughout the component
- remove all references to ‘this’ throughout the component
- Set initial state with useState()
- change this.setState() … instead, call the function that you named in the previous step to update the state…
- replace compentDidMount with useEffect
- replace componentDidUpdate with useEffect
Upvotes: 13