Помогите переписать с классового компонента под функциональный с хуками React

Это подключение к бэкенду

export const varibales={
API_URL:"http://localhost:21471/api/"

}

Класс который необходимо переписать под функцию

export class Users extends Component {

constructor(props) {
    super(props);

    this.state = {
        users: [],
        modalTitle: '',
        UserId: 0,
        FirstName: '',
        LastName: '',
        UserPassword: '',

        UserIdFilter: '',
        FirstNameFilter: '',
        LastNameFilter: '',
        usersWithoutFilter: []
    }
}

//News!!
FilterFn() {
    var UserIdFilter = this.state.UserIdFilter;
    var FirstNameFilter = this.state.FirstNameFilter;
    var LastNameFilter = this.state.LastNameFilter;

    var filteredData = this.state.usersWithoutFilter.filter(
        function (el) {
            return el.UserId.toString().toLowerCase().includes(
                UserIdFilter.toString().trim().toLowerCase()
            ) &&
                el.FirstName.toString().toLowerCase().includes(
                    FirstNameFilter.toString().trim().toLowerCase()
                ) &&
                el.LastName.toString().toLowerCase().includes(
                    LastNameFilter.toString().trim().toLowerCase()
                )
        }
    );

    this.setState({ users: filteredData });
}

changeUserIdFilter = (e) => {
    this.state.UserIdFilter = e.target.value;
    this.FilterFn();
}
changeFirstNameFilter = (e) => {
    this.state.FirstNameFilter = e.target.value;
    this.FilterFn();
}
changeLastNameFilter = (e) => {
    this.state.LastNameFilter = e.target.value;
    this.FilterFn();
}

refreshList() {
    fetch(varibales.API_URL + 'users')
        .then(response => response.json())
        .then((data) => {
            this.setState({ users: data, usersWithoutFilter: data });
        });
}

componentDidMount() {
    this.refreshList();
}

changeFirstName = (u) => {
    this.setState({ FirstName: u.target.value });
}
changeLastName = (u) => {
    this.setState({ LastName: u.target.value });
}
changeUserPassword = (u) => {
    this.setState({ UserPassword: u.target.value });
}

addClick() {
    this.setState({
        modalTitle: 'Add User',
        UserId: 0,
        FirstName: '',
        LastName: '',
        UserPassword: ''
    });
}

editClick(usr) {
    this.setState({
        modalTitle: 'Edit User',
        UserId: usr.UserId,
        FirstName: usr.FirstName,
        LastName: usr.LastName,
        UserPassword: usr.UserPassword
    })
}

createClick() {
    fetch(varibales.API_URL + 'users', {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            FirstName: this.state.FirstName,
            LastName: this.state.LastName,
            UserPassword: this.state.UserPassword
        })
    })
        .then(res => res.json())
        .then((result) => {
            alert(result);
            this.refreshList();
        }, (error) => {
            alert("Failed");
        })
}

updateClick() {
    fetch(varibales.API_URL + 'users', {
        method: 'PUT',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            UserId: this.state.UserId,
            FirstName: this.state.FirstName,
            LastName: this.state.LastName,
            UserPassword: this.state.UserPassword
        })
    })
        .then(res => res.json())
        .then((result) => {
            alert(result);
            this.refreshList();
        }, (error) => {
            alert("Failed");
        })
}

deleteClick(id) {
    if (window.confirm('Are you sure?')) {
        fetch(varibales.API_URL + 'users/' + id, {
            method: 'DELETE',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            }
        })
            .then(res => res.json())
            .then((result) => {
                alert(result);
                this.refreshList();
            }, (error) => {
                alert("Failed");
            })
    }
}

render() {
    const {
        users,
        modalTitle,
        UserId,
        FirstName,
        LastName,
        UserPassword
    } = this.state;

    return (
        <div>

            <button type="button" className="btn btn-primary m-2 float-end" data-bs-toggle="modal" data-bs-target="#exampleModal"
                onClick={() => this.addClick()} >
                Add User
            </button>

            <table className="table table-striped">
                <thead>
                    <tr>
                        <th>
                            <input className="form-control m-2" onChange={this.changeUserIdFilter} placeholder='Filter' />
                            UserId
                        </th>
                        <th>
                            <input className="form-control m-2" onChange={this.changeFirstNameFilter} placeholder='Filter' />
                            FirstName
                        </th>
                        <th>
                            <input className="form-control m-2" onChange={this.changeLastNameFilter} placeholder='Filter' />
                            LastName
                        </th>
                        <th>
                            UserPassword
                        </th>
                        <th>
                            Options
                        </th>
                    </tr>
                </thead>
                <tbody>
                    {users.map(user =>
                        <tr key={user.UserId}>
                            <td>{user.UserId}</td>
                            <td>{user.FirstName}</td>
                            <td>{user.LastName}</td>
                            <td>{user.UserPassword}</td>
                            <td>
                                <button type='button' className='btn btn-light mr-1' data-bs-toggle='modal' data-bs-target='#exampleModal'
                                    onClick={() => this.editClick(user)} >
                                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-pencil-square" viewBox="0 0 16 16">
                                        <path d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z" />
                                        <path fillRule="evenodd" d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z" />
                                    </svg>
                                </button>
                                <button type='button' className='btn btn-light mr-1'
                                    onClick={() => this.deleteClick(user.UserId)}>
                                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-trash" viewBox="0 0 16 16">
                                        <path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
                                        <path fillRule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
                                    </svg>
                                </button>
                            </td>

                        </tr>
                    )}
                </tbody>
            </table>

            <div className="modal fade" id="exampleModal" tabIndex="-1" aria-hidden="true">
                <div className="modal-dialog modal-lg modal-dialog-centered">
                    <div className="modal-content">
                        <div className="modal-header">
                            <h5 className="modal-title">{modalTitle}</h5>
                            <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                        </div>

                        <div className="modal-body">
                            <div className="input-group mb-3">
                                <span className="input-group-text">FirstName</span>
                                <input type="text" className="form-control" value={FirstName} onChange={this.changeFirstName} />
                            </div>

                            <div className="input-group mb-3">
                                <span className="input-group-text">LastName</span>
                                <input type="text" className="form-control" value={LastName} onChange={this.changeLastName} />
                            </div>

                            <div className="input-group mb-3">
                                <span className="input-group-text">UserPassword</span>
                                <input type="text" className="form-control" value={UserPassword} onChange={this.changeUserPassword} />
                            </div>

                            {UserId == 0 ?
                                <button type="button" className="btn btn-primary float-start" data-bs-dismiss="modal"
                                    onClick={() => this.createClick()}>Create</button>
                                : null}

                            {UserId != 0 ?
                                <button type="button" className="btn btn-primary float-start" data-bs-dismiss="modal"
                                    onClick={() => this.updateClick()}>Update</button>
                                : null}

                        </div>
                    </div>
                </div>
            </div>
        </div>
    )
}

}


Ответы (1 шт):

Автор решения: Color kat

Я думаю, что лучше, если вы это сделаете сами) Ибо реакт разработчик обязан уметь использовать функциональные компоненты. По сути вам здесь нужно заменить this.state на useState, а также componentDidMount на useEffect.

// Было 
componentDidMount() {
    this.refreshList();
}

// Стало
useEffect(() => {
    this.refreshList();
}, []);

// Было
this.state = {
      users: [],
      modalTitle: '',
      UserId: 0,
      FirstName: '',
      LastName: '',
      UserPassword: '',

      UserIdFilter: '',
      FirstNameFilter: '',
      LastNameFilter: '',
      usersWithoutFilter: []
}

// Стало
const [users, setUsers] = useState([]);
const [modalTitle, setModalTitle] = useState('');
const [data, setData] = useState([
  UserId: 0,
  FirstName: '',
  LastName: '',
  UserPassword: ''
]);

// И тд... Вместо this.setState используйте setUsers для поля users, setData для полей UserId, FirstName...

https://ru.reactjs.org/docs/hooks-intro.html

→ Ссылка