我正在学习 React 并创建了一个两页应用程序。第一个向用户展示数据库中的客户列表,其中包含“添加”、“编辑”、“删除”、“查看”按钮,即我的“App.js”。第二个展示了一个使用 CustomerForm 组件的“对话框”,当四个变量之一设置为 true(isAdding、isEditing、isDeleting、isViewing)时,该对话框可见。
CustomerForm.js 将客户记录中的字段显示为输入框,并应允许用户对它们执行适当的操作。当用户单击编辑时,我已经显示了数据,但字段显示为不可编辑。该问题与以下
value
属性相关:
value={customer != null ? customer[field.name] : ""}
当我省略此选项时,文本是可编辑的,但不会显示客户记录。 App.css、CustomerForm.css 和 CustomerForm.js 的完整列表如下:
应用程序.css:
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
button {
border: none; /* Remove the border */
border-radius: 0; /* Make the corners square (0 radius) */
box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3); /* Shadow to the bottom-right */
padding: 5px 10px; /* vert, horiz. Add some padding */
background-color: darkgray; /* Button background color */
color: #FFFFFF; /* Button text color */
font-size: small; /* Font size */
cursor: pointer; /* Show a pointer cursor on hover */
outline: none; /* Remove the default outline on focus */
margin: 4px 4px; /* very, horiz. Add horizontal space between buttons */
}
h1 {
color: black;
font-weight: bold;
font-family: 'Verdana', 'Arial', 'Helvetica', sans-serif;
font-size: x-large;
}
th {
background-color: darkgray;
color: white;
font-weight: normal;
font-family: 'Verdana', 'Arial', 'Helvetica', sans-serif;
font-size: small; /* Font size */
margin: 0 4px; /* Add horizontal space between buttons */
text-align: left;
}
td {
/* background-color: lightgray;*/
font-family: 'Verdana', 'Arial', 'Helvetica', sans-serif;
font-size: small;
text-align: left;
}
.note {
color: black;
font-style: italic;
font-family: 'Verdana', 'Arial', 'Helvetica', sans-serif;
font-size: x-small;
}
.selectedCustomer {
background-color: blue; /* Color for the highlighted row */
color: white;
cursor: pointer;
}
.customer {
background-color: lightgray;
color: black;
cursor: pointer;
}
CustomerForm.css:
.modal-overlay { /* this is for a window-sized <div> that stops interaction with the items below it */
position: fixed; /* the overlay stays in place regardless of scrolling */
top: 0; /* top-left of overlay */
left: 0;
width: 100%; /* from top-left, this covers the entire window, no matter what is done to the window */
height: 100%;
background: rgba(0, 0, 0, 0.5); /* drop the visibility of everything behind by 50% */
display: flex; /* These flexbox properties center the modal dialog horizontally and vertically within the overlay. The combination of justify-content: center; and align-items: center; ensures that the .modal-content (the dialog) is always in the middle of the screen, providing a focused area for user interaction. */
justify-content: center;
align-items: center;
}
.modal-content {
background: white;
padding: 20px;
border-radius: 5px;
width: auto;
height: auto;
max-width: 500px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
.buttonBar {
text-align: right;
}
.editableInput {
background-color: white;
}
.nonEditableInput {
background-color: lightBlue;
}
td {
padding-right: 10px; /* Adds padding to the right side of the cell */
}
CustomerForm.js:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import FormModes from './FormModes';
import './CustomerForm.css'; // Include CSS for modal styling
const CustomerForm = ({ customer, mode, onClose }) =>
{
const [formData, setFormData] = useState((customer != null) ?
customer :
{
CustomerID: '',
CustomerName: '',
Address1: '',
Address2: '',
Address3: '',
Town: '',
Postcode: '',
Country: '',
PhoneNumber: '',
CustomerID: '',
});
const [formMode, setFormMode] = useState(mode);
const [error, setError] = useState(null);
const formFields = // array of fields to show
[
{label:'Customer Name', type:'text', name:'CustomerName'},
{label:'Address 1', type:'text', name:'Address1'},
{label:'Address 2', type:'text', name:'Address2'},
{label:'Address 3', type:'text', name:'Address3'},
{label:'Town', type:'text', name:'Town'},
{label:'Postcode', type:'text', name:'Postcode'},
{label:'Country', type:'text', name:'Country'},
{label:'Phone Number', type:'text', name:'PhoneNumber'},
];
const buttonText = () =>
{
switch (formMode)
{
case FormModes.Add: return "Add";
case FormModes.Edit: return "Update";
case FormModes.Delete: return "DELETE";
case FormModes.View: return "Close";
default: throw new Error("Unknown formMode: ${formMode}")
}
};
const isReadOnly = () =>
{
return ((formMode==FormModes.Delete) || (formMode==FormModes.View));
};
const handleSubmit = async (event) =>
{
try
{
event.preventDefault(); // this stops the default submit action
switch (formMode)
{
case FormModes.Add:
break;
case FormModes.Edit:
const response = await axios.post('/api/customers', formData);
break;
case FormModes.Delete:
break;
case FormModes.View:
break;
default:
throw new Error('Unknown form Mode ${formMode}.')
}
onClose();
} catch (err) {
setError(err.message);
}
};
return (
<div className="modal-overlay">
<div className="modal-content">
<h2>{formMode} Customer</h2>
<form onSubmit={handleSubmit}>
<table border="0">
{formFields.map((field) =>
<tr key={field.CustomerID}>
<td padding-right="10px"><label>{field.label}</label></td>
<td><input type={field.type}
name={field.name}
value={(customer != null) ? customer[field.name] : ""}
placeholder={field.label}
readOnly={isReadOnly()}
className={isReadOnly() ? "nonEditableInput" : "editableInput"}
/>
</td>
</tr>
)}
</table>
<div className="buttonBar">
<button type="submit">{buttonText()}</button>
<button type="button" onClick={onClose}>Cancel</button>
{error && <p>Error: {error}</p>}
</div>
</form>
</div>
</div>
);
};
export default CustomerForm;
我的问题是,为什么要包括这一行:
value={customer != null ? customer[field.name] : ""}
将输入字段锁定为该值?我只是想在显示字段时设置它并且可以编辑。
您已通过以编程方式设置
value
创建了“受控组件”。这可以防止浏览器更改该值。您要么需要添加一个 onChange
属性,并带有一个处理程序来更新 value
属性上设置的值,要么需要删除 value
属性。
请参阅 React 文档中的 input
中的
“我的文本输入在输入时不会更新”。