我在下面的React页面中调用了一个组件,该组件生成一个具有一些额外功能的文本字段,例如:将值复制到剪贴板或显示字符数。我遇到的问题是,当我试图从页面传递值时,它不起作用。
页面代码为:
import React, {useEffect, useRef, useState} from 'react'
import {useNavigate, useParams} from 'react-router-dom'
import {enterprise_info} from "../../config/AlertInfo";
import Header from '../../layouts/Header'
import EnterpriseMenu from "../../pages/enterprises/EnterpriseMenu";
import GetPermissionsMessage from "../../hooks/GetPermissionsMessage";
import Horizontal from "../../components/navigation/horizontal";
import Preloader from "../../components/card/Preloader";
import Alert from "../../components/alert/Alert";
import Text from "../../components/inputs/Text";
import Email from "../../components/inputs/Email";
import Button from "../../components/inputs/Button";
import UseGetFormData from "../../hooks/UseGetFormData";
import UseRequest from "../../hooks/UseRequest"
const EnterpriseInfo = () => {
const {id} = useParams()
const formRef = useRef()
const history = useNavigate();
const [errors, setErrors] = useState({})
const [loading, setLoading] = useState(true)
const [preloader, setPreloader] = useState({})
const [enterprise, setEnterprise] = useState({})
const fetchEnterprise = async () => {
return await (await UseRequest(
`/enterprises/get`,
{request: {method: 'PUT', data: {limit: 1, offset: 0, _id: id}}}
)).json();
}
useEffect(() => {
const message = GetPermissionsMessage('enterprises', 'upsert')
if(message){
setPreloader({
title: "You don't have permissions",
description: message
})
}
if (id != undefined) {
fetchEnterprise().then((response) => {
if(response?.entities?.length){
setEnterprise(response.entities[0])
setLoading(false)
}
});
}
setLoading(false)
}, [])
const handleSave = async (ev) => {
ev.preventDefault()
const formData = UseGetFormData(formRef)
const response = await (await UseRequest(
`/enterprises/upsert/${id ?? ''}`, {
request: {
method: 'POST', data: {
name : formData.get('name'),
email : formData.get('email'),
phone : formData.get('phone'),
website: formData.get('website'),
vat : formData.get('vat'),
}
}
})).json();
if (response.errors) {
setErrors(response.errors)
}
if (!id && response._id) {
history(`/enterprises/edit/${response._id}`)
}
}
return (
<div className="Enterprise">
<Header title="Enterprise Manager" icon="enterprise"/>
<div className="card">
<Preloader loading={loading} title={preloader?.title} description={preloader.description} />
{id && <Horizontal {...EnterpriseMenu} />}
<form ref={formRef} className="max-width-500">
<Alert icon="info" type="primary" message={enterprise_info}/>
<Text required copy
name="name"
label="Name"
error={errors.name}
value={enterprise.name}
placeholder="Type company name"
/>
<Email required
name="email"
label="Email"
error={errors.email}
value={enterprise.email}
placeholder="Type company email"
/>
<Text required
name="phone"
label="Phone"
error={errors.phone}
value={enterprise.phone}
placeholder="Type company phone"
/>
<Text
name="website"
label="Website"
error={errors.website}
value={enterprise.website}
placeholder="Type company website"
/>
<Text
name="vat"
label="Vat number"
error={errors.vat}
value={enterprise.vat}
placeholder="Type vat number"
/>
<Button type="primary" label="Save" icon="check"
onClick={handleSave}
/>
</form>
</div>
</div>
)
}
export default EnterpriseInfo;
下面是文本组件的代码,其中inputValue没有更新。
我曾尝试直接使用由参数提供的{value}字段作为defaultValue,但这样做时,我无法读取值的长度,也无法在用户修改后将其复制到剪贴板。
我还尝试调用useEffect作为dependency [value],但它也不起作用。
import React, {useState} from "react";
import Icon from "../icon/Icon";
import UseCopyToClipboard from "../../hooks/UseCopyToClipboard";
const Text = (props) => {
const {
name, label, value, error, counter, copy, required,
placeholder, className, onChange, onBlur, ...rest
} = props
const [inputValue, setInputValue] = useState(value)
const handleChange = (ev) => {
setInputValue(ev.target.content)
if (typeof onChange == "function") {
onChange(ev)
}
}
const handleCopy = () => {
UseCopyToClipboard(inputValue)
}
return (
<React.Fragment>
<div className="form-group">
{label && <label className="Label">
{required && <span className="text-red required">* </span>}{label}
{error && <span className="error">{error}</span>}
</label>}
<div className="Input input-container">
<input
name={name}
type="text"
autoComplete="off"
value={inputValue}
onChange={handleChange}
placeholder={placeholder}
className={`form-control ${className ?? ''}`}
{...rest}
/>
{counter && <span className="counter">{inputValue.length}</span>}
{copy && <span className="copy" onClick={handleCopy}><Icon name="copy"/></span>}
</div>
</div>
</React.Fragment>
)
}
export default Text;
1条答案
按热度按时间qni6mghb1#
问题可能在于您在
enterprise
加载之前显示组件,这意味着状态enterprise
==={}
,结果是您传递给Text
的值未定义,inputValue
的初始状态也未定义。对此有一些解决方案:
1.直到
enterprise has a value
才呈现窗体1.删除子状态,并将
enterprise
用于所有内容,只需将一个on更改传递给所使用的Text组件即可1.向窗体中添加一个键以在键更改时触发重新呈现
最后一点:你的句柄改变功能也可能是一个因素。你使用
setInputValue(ev.target.content)
把它改变成setInputValue(ev.target.value)