3

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>
    );
  }}
1

1 Answer 1

13

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:

  1. use function instead of class
  2. remove the constructor
  3. remove the render() method, keep the return
  4. add const before all methods
  5. remove this.state throughout the component
  6. remove all references to ‘this’ throughout the component
  7. Set initial state with useState()
  8. change this.setState() … instead, call the function that you named in the previous step to update the state…
  9. replace compentDidMount with useEffect
  10. replace componentDidUpdate with useEffect

More detail

Sign up to request clarification or add additional context in comments.

5 Comments

i have confusion of adding row func for converting addRow(e) { e.preventDefault(); var newdata = { name: this.state.Namefield.value, mobile: this.state.Mobilefield.value, mail: this.state.Emailfield.value } this.setState({ tablerows: this.state.tablerows.concat(newdata), flag: true }); const name1 = this.state.Namefield; const mob1 = this.state.Mobilefield; if (name1.value !== "") const newName = [...this.state.fields, name1] this.setState({ fields: newName, Namefield: { value: '', error: ''
@nismapokharel why you are confused? that's so easy. I provided a link, you can go through that link and I am sure it will be clear after completing that article.
@nismapokharel I converted addRow function and updated the answer. pls check it
confusion on function Editrow and addrow .can you illusrate more about it?
it is very hard to teach you React here. but in short I can say you need remove the word this as it is not supported in functional component

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.