最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - convert react class-based to functional component - Stack Overflow

programmeradmin4浏览0评论

I am new to learning react and I am having a tough time converting class ponents into functional ponents 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>
    );
  }}

I am new to learning react and I am having a tough time converting class ponents into functional ponents 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>
    );
  }}
Share Improve this question edited Mar 23, 2023 at 8:43 Khabir 5,8521 gold badge25 silver badges38 bronze badges asked Nov 14, 2021 at 17:08 nisma pokharelnisma pokharel 391 gold badge2 silver badges4 bronze badges 1
  • I would suggest reading this nimblewebdeveloper./blog/… – Sachin Yadav Commented Nov 14, 2021 at 19:05
Add a ment  | 

1 Answer 1

Reset to default 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 ponent
  6. remove all references to ‘this’ throughout the ponent
  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 pentDidMount with useEffect
  10. replace ponentDidUpdate with useEffect

More detail

发布评论

评论列表(0)

  1. 暂无评论