Мне дали задание обновить и улучшить пользовательский интерфейс существующего приложения React без предварительного знания GraphQL, так что это мой первый раз. Это простое приложение, в котором вы можете редактировать и удалять элементы. Моя задача - стилизовать и добавить функциональность в режиме реакции для форм Edit и Update . После добавления функций модальное окно работает так же, как и обработчик изменений для каждой формы, но функции редактирования и удаления больше не работают. Нужна помощь.
Вот старый код для элемента списка без реактивного модального окна:
import React, { useState } from 'react';
import styled from 'styled-components';
import { EXECUTE } from '@nostack/no-stack';
import compose from '@shopify/react-compose';
import { graphql } from '@apollo/react-hoc';
import {
UPDATE_ITEM_FOR_LIST_ACTION_ID,
DELETE_ITEM_FOR_LIST_ACTION_ID,
} from '../../../config';
import EditInstanceForm from '../../EditInstanceForm';
import DeleteInstanceMenu from '../../DeleteInstanceMenu';
import ItemStyleWrapper from '../../Items';
import Button from '../../Items';
function Item({
item,
parentId,
selected,
updateInstance,
deleteInstance,
refetchQueries,
onSelect,
}) {
const [itemValue, updateItemValue] = useState(item.value);
const [isEditMode, updateIsEditMode] = useState(false);
const [isSaving, updateIsSaving] = useState(false);
const [isDeleteMode, updateIsDeleteMode] = useState(false);
const [isDeleting, updateIsDeleting] = useState(false);
if (!selected) {
return (
<ItemStyleWrapper onClick={() => onSelect(item.id)}>
{itemValue}
</ItemStyleWrapper>
);
}
function handleItemValueChange(e) {
updateItemValue(e.target.value);
}
async function handleItemValueSave() {
updateIsSaving(true);
await updateInstance({
variables: {
actionId: UPDATE_ITEM_FOR_LIST_ACTION_ID,
executionParameters: JSON.stringify({
value: itemValue,
instanceId: item.id,
}),
},
refetchQueries,
});
updateIsEditMode(false);
updateIsSaving(false);
console.log('Saving');
}
function handleCancelEdit() {
updateIsEditMode(false);
}
if (isEditMode) {
return (
<ItemStyleWrapper>
<EditInstanceForm
id={item.id}
label='Item Value:'
value={itemValue}
onChange={handleItemValueChange}
onSave={handleItemValueSave}
onCancel={handleCancelEdit}
disabled={isSaving}
/>
</ItemStyleWrapper>
);
}
async function handleDelete() {
updateIsDeleting(true);
try {
await deleteInstance({
variables: {
actionId: DELETE_ITEM_FOR_LIST_ACTION_ID,
executionParameters: JSON.stringify({
parentInstanceId: parentId,
instanceId: item.id,
}),
},
refetchQueries,
});
} catch (e) {
updateIsDeleting(false);
}
console.log('Deleting');
}
function handleCancelDelete() {
updateIsDeleteMode(false);
}
if (isDeleteMode) {
return (
<ItemStyleWrapper selected={selected} isDeleting={isDeleting}>
{itemValue}
<DeleteInstanceMenu
onDelete={handleDelete}
onCancel={handleCancelDelete}
disabled={isDeleting}
/>
</ItemStyleWrapper>
);
}
return (
<ItemStyleWrapper selected={selected}>
{itemValue}
<Button type='button' onClick={() => updateIsEditMode(true)}>
✎
</Button>
<Button type='button' onClick={() => updateIsDeleteMode(true)}>
🗑
</Button>
</ItemStyleWrapper>
);
}
export default compose(
graphql(EXECUTE, { name: 'updateInstance' }),
graphql(EXECUTE, { name: 'deleteInstance' })
)(Item);
Вот новый и обновленный код того же компонента:
import React, { useState } from 'react';
import styled from 'styled-components';
import { EXECUTE } from '@nostack/no-stack';
import compose from '@shopify/react-compose';
import { graphql } from '@apollo/react-hoc';
import ModalContainer from '../../Modals/ModalContainer';
import '../../Modals/modals.css';
import { FaCheck, FaTrashAlt, FaEdit } from 'react-icons/fa';
import {
UPDATE_ITEM_FOR_LIST_ACTION_ID,
DELETE_ITEM_FOR_LIST_ACTION_ID,
} from '../../../config';
import EditInstanceForm from '../../EditInstanceForm';
import DeleteInstanceMenu from '../../DeleteInstanceMenu';
import ItemStyleWrapper from '../../Items';
import Button from '../../Items';
import ItemCheckBox from '../../Items';
import ItemValueContainer from '../../Items';
function Item({
item,
parentId,
selected,
updateInstance,
deleteInstance,
refetchQueries,
onSelect,
}) {
const [itemValue, updateItemValue] = useState(item.value);
const [editModal, setEditModal] = useState(false);
const [isSaving, updateIsSaving] = useState(false);
const [deleteModal, setDeleteModal] = useState(false);
const [isDeleting, updateIsDeleting] = useState(false);
const [isChecked, updateIsChecked] = useState(false);
const handleEditModal = () => setEditModal((prevState) => !prevState);
const handleDeleteModal = () => setDeleteModal((prevState) => !prevState);
if (!selected) {
return (
<ItemStyleWrapper>
<ItemCheckBox htmlFor={item.id}>
<input
type='checkbox'
id={item.id}
checked={isChecked}
onChange={handleItemCheckedStatus}
/>
<FaCheck />
</ItemCheckBox>
<ItemValueContainer
onClick={() => onSelect(item.id)}
isChecked={isChecked}
>
{itemValue}
</ItemValueContainer>
</ItemStyleWrapper>
);
}
function handleItemCheckedStatus() {
updateIsChecked((previousState) => !previousState);
}
function handleItemValueChange(e) {
updateItemValue(e.target.value);
console.log(itemValue);
}
async function handleItemValueSave() {
updateIsSaving(true);
await updateInstance({
variables: {
actionId: UPDATE_ITEM_FOR_LIST_ACTION_ID,
executionParameters: JSON.stringify({
value: itemValue,
instanceId: item.id,
}),
},
refetchQueries,
});
updateIsSaving(false);
await handleEditModal();
console.log('Saving');
}
function handleCancelEdit() {
handleEditModal();
}
async function handleDelete() {
updateIsDeleting(true);
try {
await deleteInstance({
variables: {
actionId: DELETE_ITEM_FOR_LIST_ACTION_ID,
executionParameters: JSON.stringify({
parentInstanceId: parentId,
instanceId: item.id,
}),
},
refetchQueries,
});
await handleDeleteModal();
} catch (e) {
updateIsDeleting(false);
}
console.log('Deleting');
}
function handleCancelDelete() {
handleDeleteModal();
}
return (
<ItemStyleWrapper selected={selected}>
<ItemCheckBox htmlFor={item.id}>
<input
type='checkbox'
id={item.id}
checked={isChecked}
onChange={handleItemCheckedStatus}
/>
</ItemCheckBox>
<ItemValueContainer>{itemValue}</ItemValueContainer>
<Button type='button' onClick={handleEditModal}>
<FaEdit />
</Button>
<Button type='button' onClick={handleDeleteModal}>
<FaTrashAlt />
</Button>
<ModalContainer status={editModal} exitHandler={handleEditModal}>
<div className='modal-body'>
<EditInstanceForm
id={item.id}
label='Item Value:'
value={itemValue}
onChange={handleItemValueChange}
onSave={handleItemValueSave}
onCancel={handleCancelEdit}
disabled={isSaving}
/>
</div>
</ModalContainer>
<ModalContainer status={deleteModal} exitHandler={handleDeleteModal}>
<div className='modal-body'>
<ItemValueContainer>{itemValue}</ItemValueContainer>
<DeleteInstanceMenu
onDelete={handleDelete}
onCancel={handleCancelDelete}
disabled={isDeleting}
/>
</div>
</ModalContainer>
</ItemStyleWrapper>
);
}
export default compose(
graphql(EXECUTE, { name: 'updateInstance' }),
graphql(EXECUTE, { name: 'deleteInstance' })
)(Item);
А вот и реакционно-модальный код:
import React from 'react';
import Modal from 'react-modal';
import './modals.css';
const ModalContainer = ({ children, status, exithandler }) => {
return (
<Modal isOpen={status} onRequestClose={exithandler}>
{children}
</Modal>
);
};
export default ModalContainer;