首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >支持回调,以便在使用React窗体验证时更改另一个字段值

支持回调,以便在使用React窗体验证时更改另一个字段值
EN

Stack Overflow用户
提问于 2020-12-01 16:20:16
回答 1查看 5.5K关注 0票数 3

TL;DR

这工作:https://codesandbox.io/s/stoic-beaver-ucydi

使用refactor表单重构后,此操作不起作用:https://codesandbox.io/s/objective-cloud-bkunr?file=/src/ControlledTextField.tsx

长话短说

没有反应钩形式(工作确定)

最近,我使用Fluent UI和自定义组件中的包装字段构建了一个有状态的React表单。

我包含了一个特性,在输入Site字段时生成Site字段中的值(在我的示例中,它只是复制字段值并删除URL无效的字符)。

(简化的)代码运行良好,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import * as React from 'react';
import {useState} from 'react';
import { PrimaryButton } from 'office-ui-fabric-react';
import SiteTitleField from '../../../common/formFields/SiteTitleField';
import SiteUrlField from '../../../common/formFields/SiteUrlField';

export default function MyForm(props) {

  const urlPrefix: string = "https://" + window.location.hostname + "/sites/";

  const [siteTitle, setSiteTitle] = useState();
  const [titleErrorMessage, setTitleErrorMessage] = useState('');

  const [siteUrl, setsiteUrl] = useState();
  const [urlErrorMessage, setUrlErrorMessage] = useState('');

  function handleTitleChange(e) {
    if (e.target.value.length) {
      setTitleErrorMessage('');
    } else {
      setTitleErrorMessage('This field is required.');
    }
    setSiteTitle(e.target.value);
    setsiteUrl(e.target.value.replace(/[^A-Za-z0-9_-]/g, ""));
  }
  
  function handleUrlChange(e) {
    if (e.target.value.length) {
      setUrlErrorMessage('');
    } else {
      setUrlErrorMessage('This field is required.');
    }
    setsiteUrl(e.target.value);
  }
  
  function handleButtonClick(e) {
    // call to API
  }

  return (
    <SiteTitleField
      siteTitle={siteTitle}
      titleErrorMessage={titleErrorMessage}
      handleTitleChange={handleTitleChange}
    />

    <SiteUrlField
      siteUrl={siteUrl}
      urlErrorMessage={urlErrorMessage}
      urlPrefix={urlPrefix}
      handleUrlChange={handleUrlChange}
    />

    <PrimaryButton 
      text="Create a Request" 
      onClick={handleButtonClick}
    />
  );
}

SiteTitleField组件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import * as React from 'react';
import { TextField } from 'office-ui-fabric-react/lib/TextField';

export default function SiteTitleField(props) {
  return (
    <TextField 
      value={props.siteTitle}
      required 
      aria-required="true"
      errorMessage={props.titleErrorMessage}
      label="Site Title" 
      placeholder="Set the title of the site"
      onChange={props.handleTitleChange}
    />
  );
}

SiteUrlField组件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import * as React from 'react';
import { TextField } from 'office-ui-fabric-react/lib/TextField';

export default function SiteUrlField(props) {
  return (
    <TextField
      value={props.siteUrl}
      required
      aria-required="true"
      errorMessage={props.urlErrorMessage}
      label="Site URL"
      prefix={props.urlPrefix}
      placeholder="Set site URL alias"
      onChange={props.handleUrlChange}
    />
  );
}

使用React形式(工作不正常)

现在,我正在尝试使用refactor表单和Yup验证模式重构我的表单。

我使用组件及其呈现属性包装了Fluent UI TextField组件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import * as React from 'react';
import { Control, Controller, FieldErrors } from "react-hook-form";
import { TextField } from 'office-ui-fabric-react';

export interface IControlledTextFieldProps {
    control: Control<any>;
    name: string;
    errors: FieldErrors<any>;
    label?: string;
    prefix?: string;
    placeholder?: string;

    onChangeCallback?: (...event: any[]) => void;
    refValue?: string;
}
  
export const ControlledTextField: React.FC<IControlledTextFieldProps> = ({
  control,
  name,
  errors,
  label,
  prefix, 
  placeholder,

  onChangeCallback,
  refValue,

}) => {
  return (
    <Controller
      name={name}
      control={control}
      disabled={disabled}
      render={({ onChange, onBlur, value, name: fieldName }) => (
        <TextField

          onChange={(event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) => {onChange(refValue); onChangeCallback && onChangeCallback(event);}}
          value={refValue}

          onBlur={onBlur}
          name={fieldName}
          errorMessage={errors[fieldName] && errors[fieldName].message}
          label={label}
          prefix={prefix}
          placeholder={placeholder}
        />
      )}
    />
  );
};

我相应地替换了SiteTitleField和SiteUrlField的代码,并添加了一个简单的Yup验证模式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const schema = yup.object().shape({
  siteTitle: yup.string().required("Site Title needs to be provided."),
  siteUrl: yup.string().required("Site URL needs to be provided."),
});

const { handleSubmit, errors, control } = useForm<Inputs>({
  resolver: yupResolver(schema)
});

我用<form>标记包装了表单,并相应地更改了字段属性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<form onSubmit={handleSubmit(handleButtonClick)}>
    <SiteTitleField
      name="siteTitle"
      control={control}
      errors={errors}
      handleTitleChange={handleTitleChange}
    />
    
    <SiteUrlField
      name="siteUrl"
      control={control}
      errors={errors}
      siteUrl={siteUrl}
      urlPrefix={urlPrefix}
    />
        
    <PrimaryButton 
      text="Create a Request" 
      type="submit"
    />
</form>

关于状态,我只留下了值复制所需的东西:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  const [siteUrl, setsiteUrl] = useState();
  
  function handleTitleChange(e) {
    setsiteUrl(e.target.value.replace(/[^A-Za-z0-9_-]/g, ""));
  }

问题

我不能让React表单验证和我的值复制功能同时工作。

如果使用以下代码,验证效果很好,但用户无法编辑站点URL字段:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
onChange={(event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) => {onChange(refValue); onChangeCallback && onChangeCallback(event);}}
value={refValue}

或者复制和编辑字段值很好,但是即使输入了值,验证也表明这两个字段都是空的(必需),当使用以下代码时:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
onChange={onChangeCallback}
value={refValue}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-01 19:36:12

好吧,我想出来了。

而不是使用状态更新字段值。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  const [siteUrl, setsiteUrl] = useState();
  
  function handleTitleChange(e) {
    setsiteUrl(e.target.value.replace(/[^A-Za-z0-9_-]/g, ""));
  }

我应该使用useFormsetValue

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  const { 
    handleSubmit, 
    errors, 
    control, 
    setValue // added
  } = 
  useForm<Inputs>({
    resolver: yupResolver(schema)
  });

  function handleTitleChange(e) {
    // changed:
    setValue("siteUrl", e.target.value.replace(/[^A-Za-z0-9_-]/g, ""), {
      shouldValidate: true
    });
  }

value in ControlledTextField应该简单地解析为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
value={value}

工作解决方案:https://codesandbox.io/s/focused-montalcini-ehbp3?file=/src/App.tsx

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65100499

复制
相关文章
避免在Pod重启期间继续接收业务流量
在TKE Serverless 集群中部署了某个服务,并且通过 Loadbalancer 类型的 Service 来暴露服务,接受流量请求。然而,当 pod 副本发生重启时,可能依然会有业务流量请求到了 正在重启中 的 pod 副本,进而出现请求错误。
keke.wang
2023/08/17
3260
将项目部署到Tomcat服务器后从页面接收MySQL数据中文乱码
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"
星哥玩云
2022/07/24
1.7K0
将项目部署到Tomcat服务器后从页面接收MySQL数据中文乱码
『中级篇』Docker compose 部署一个复杂的应用(41)
我更新了worker目录下的Dockerfile文件,使用阿里云maven仓库地址覆盖了原来的maven地址。我是先找到docker所在的容器,通过install maven的时候maven的安装路径:/usr/share/maven/conf/ ,然后将本地的settings.xml覆盖原来的地址就可以解决了。
IT架构圈
2018/07/31
1K0
PHPStorm发布PHP代码到远程服务器
本地Windows开发PHP的时候,想在修改文件保存时,自动上传到指定(测试)服务器上,PhpStorm提供了这个功能,设置参考如下: 其中的“Upload changed files automat
joshua317
2018/04/16
1.8K0
PHPStorm发布PHP代码到远程服务器
从内核接收数据到EPOLL原理
1.网卡发现 MAC 地址符合,就将包收进来;发现 IP 地址符合,根据 IP 头中协议项,知道上一层是 TCP 协议;
ruochen
2021/11/25
1.1K0
在Docker中运行Jenkins实现代码自动发布到测试服务器
可参考:https://github.com/jenkinsci/docker/blob/master/README.md 另外:jenkins_home 默认在docker目录下,如:/var/lib/docker/volumes/jenkins_home, workspace目录也在此目录下,通过源码管理拉取代码也会放在workspace下,你可以通过脚本或其他方法发布源码,或者构建成docker image等。
星哥玩云
2022/07/28
1.3K0
在Kubernetes上运行有状态应用:从StatefulSet到Operator
一开始Kubernetes只是被设计用来运行无状态应用,直到在1.5版本中才添加了StatefulSet控制器用于支持有状态应用,但它直到1.9版本才正式可用。本文将介绍有状态和无状态应用,一个通过K8S StatefulSet来编排有状态应用的示例,以及当前有状态应用容器化现状及将来的发展趋势。
SammyLiu
2019/12/12
1.9K0
在Kubernetes上运行有状态应用:从StatefulSet到Operator
『中级篇』Docker compose 部署一个复杂的应用(41)
我更新了worker目录下的Dockerfile文件,使用阿里云maven仓库地址覆盖了原来的maven地址。我是先找到docker所在的容器,通过install maven的时候maven的安装路径:/usr/share/maven/conf/ ,然后将本地的settings.xml覆盖原来的地址就可以解决了。
IT架构圈
2018/08/01
7090
『中级篇』Docker compose 部署一个复杂的应用(41)
到 2025 年,800 Gbps 端口将超过 400 Gbps?!
Dell'Oro Group 最近发布的一份《以太网交换机五年预测》报告显示,2021 年至 2026 年间,以太网交换机数据中心市场预计将以接近两位数的复合年增长率增长,未来5年累计支出将接近1000亿美元。预计 400 Gbps 及更高的速度将占支出的一半,到 2025 年,800 Gbps 将超过 400 Gbps。 “到 2026 年,云服务提供商预计将占数据中心交换机支出的 60%,并推动 400 Gbps、800 Gbps 和 1600 Gbps 速度的采用,”Dell'Oro Group 高级
SDNLAB
2022/07/19
1.3K0
到 2025 年,800 Gbps 端口将超过 400 Gbps?!
mooon-agent接收状态机代码摘要
recv_machine.h #ifndef MOOON_AGENT_RECV_MACHINE_H #define MOOON_AGENT_RECV_MACHINE_H #include <agent/message.h> AGENT_NAMESPACE_BEGIN class CAgentThread; class CRecvMachine { private: /*** * 接收状态值 */     typedef enum recv_state_t {      
一见
2018/08/07
2870
nginx返回400状态码
2.确认是url加上参数后,nginx返回400,并且nginx除了400状态码的访问日志,没有输出其他异常日志;
全栈程序员站长
2022/11/17
2K0
SwiftU:将状态绑定到UI控件
SwiftUI的@State属性包装器允许我们自由修改视图结构体,这意味着当程序更改时,我们可以更新视图属性以匹配。
韦弦zhy
2020/03/20
2.9K0
在 Windows 安装期间将 MBR 磁盘转换为 GPT 磁盘
2018-02-22 14:13
walterlv
2018/09/18
1.2K0
将项目发布到jcenter仓库
将项目发布到jcenter仓库可以方便他人直接使用,下面总结一下流程和可能遇到的问题
杜金房
2020/12/21
1.2K0
将项目发布到jcenter仓库
解决在控制层springmvc框架发出的400状态的错误
错误场景: 错误分析:   这也是我第一次遇到这个类型的异常,400响应状态代表:客户端发出的请求中携带的参数与服务器端接受的参数类型不匹配,进一步就是说我后台的实体类中数据类型为Date,而前台传递
赵小忠
2018/01/24
2K0
将项目发布到 Homebrew 官方仓库
Homebrew 标榜自己是 “macOS(或 Linux)缺失的软件包的管理器”,使用 macOS 作为开发终端的用户,往往绕不过 brew 这个软件包管理工具。确实在 macOS 上没有比 brew 更好用的软件包管理工具了,基本上想用的 CLI 工具,只需一行命令就可一键安装,非常的方便。记得去年博主还写过一篇 《Golang 装逼指南 Ⅱ:在 Homwebrew 上发布 Golang 项目》,当时只是介绍了如何将 Golang 开发的 CLI 工具发布到自建的 homebrew-tap 上。本文则是讲解如何将自己开发的软件,推送到官方的 homebrew-core[1] 仓库中,使用像 brew install kubecm 这样的命令即可完成安装。
郭旭东
2020/12/30
1.7K0
将项目发布到 Homebrew 官方仓库
Java Maven Settings配置参考
settings.xml文件中的 settings 元素包含用于定义以各种方式配置Maven执行的值的元素,如pom.xml,但不应绑定到任何特定项目或分发给受众。这些值包括本地仓库位置、备用远程仓库服务器和身份验证信息。
授客
2023/07/25
2.3K0
Java Maven Settings配置参考
发布制品到私服 Nexus
在项目中,有些通用的代码模块,有时候不想通过拷贝这么简单的方式粗暴地实现复用。因为这样不仅体现不了 jar 包的 class 变更的实时性,而且也不利于 jar 统一管理。使用maven deploy的方式,将通用的模块打成 jar 包,发布到 Nexus 服务,让其他的项目来引用,以简洁、高效的方式来实现 jar 复用和管理。
BUG弄潮儿
2022/04/15
3790
发布制品到私服 Nexus
有状态容器应用,从入门到实践
什么是无状态或有状态容器呢?所谓无状态容器应用,意味着容器上应用所使用的历史数据或运行状态不需要进行持久化,重新拉起这个应用时,无需关注这些历史输入。简单来说,例如你要运行一个计算器(而且这个计算器不需要支持历史记录功能),当你重新拉起这个计算器时,之前的数据不需要重新被加载上来,计算器可以认为是一个无状态应用。其它类似的无状态容器应用还包括一些协议转换、请求转发等应用,大体都可以认为是无状态的。
焱融科技
2021/03/15
9250
有状态容器应用,从入门到实践
37000 字 + 代码,艿艿肝的 Shiro 从入门到实战,直接收藏吃灰!
大家好,我是艿艿,一个让你秃头的小胖子。。。 最近状态有点小好,抠脚一算, https://github.com/YunaiV/SpringBoot-Labs 仓库的 Spring Boot、Spring Cloud、Dubbo 的示例代码,竟然要破 60000 行了 = = 默默撸了 2 年了要~
芋道源码
2020/06/24
2.5K0

相似问题

将Synapse工件发布到工作区状态

12

在发布期间无法在本地找到maven-metadata.xml。

112

阿波罗服务器部署到heroku后的“接收状态代码400”

10

CircleCI将工件发布到云服务器?

115

无法获得'https://google.bintray.com/.../maven-metadata.xml'.从服务器接收状态代码403 :禁止

28
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文