reactjs - 将基于类的 React 转换为功能组件

标签 reactjs

我是学习 React 的新手,我很难将类组件转换为功能组件以理解问题和分析。我想使用函数式方法来理解状态和生命周期方法在钩子(Hook)概念中的工作原理。

我们如何才能做到这一点?

我在类里面的代码是

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

最佳答案

您可以按照以下代码继续进行其余的代码转换。

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;

步骤如下:

  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

关于reactjs - 将基于类的 React 转换为功能组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69965343/

相关文章:

reactjs - json-server 主页未显示

node.js - 在 React on Rails 中访问 NODE_ENV 环境变量

reactjs - 使用 React-Router v6 进行身份验证后,如何将用户重定向回最初请求的页面?

javascript - setState 在函数调用中未更新

javascript - axios 在react中忽略baseURL

css - 悬停状态下的选项卡可访问性

javascript - Material-UI 和 React - 将 &lt;input&gt; 更改为 <TextField> 会阻止表单提交工作?

javascript - 使用 React hooks 获取数据清理异步回调

reactjs - 仅刷新从父级更改的组件

javascript - ES6/React 第二项绑定(bind)失败