Помогите переписать с классового компонента под функциональный с хуками 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...