繁体   English   中英

从 function 主体外部调用 React setState

[英]Calling React setState from outside of function body

我对 React 还很陌生,我试图让一些动态内容基于对 API 的调用来验证一些输入数据。

由于我使用 yup 验证的方式,我认为处理 API 调用响应的代码必须在反应 function 主体之外。 这意味着我不能使用“setOfferState”,如下面的示例所示。

我试过只用一个基本变量“offer”来做这件事,这似乎在大多数情况下都可以正常工作,但我不相信这会一直有效,因为我有时会在控制台中遇到错误并且必须重新加载页面。 我知道这不是在 React 中设置变量的正确方法。

报价和报价状态都显示在下面的示例中,但报价状态不起作用(错误:无效的挂钩调用。挂钩只能在 function 组件的主体内部调用。)


let offer = '';
const [offerState, setOfferState] = useState(0);

const schema = yup.object().shape({
  discount: yup.string().max(20).test('custom', null,
    function (value) {
      offer = '';
      setOfferState('');
      return new Promise((resolve, reject) => {
        const api = new ApiFacade();
        api.validateCode(value).then((result) => {
          offer = result.value.offerDescription;
          setOfferState(result.value.offerDescription);
        })
      })
    })
});

const YourDetails = () => {
  const formApi = useForm({
    resolver: yupResolver(schema)
  });

  const { handleSubmit, setValue, trigger } = formApi;

  return (
    <FormProvider {...formApi}>

        <form onSubmit={handleSubmit(onSubmit)}>
          
              <Input name="discount" placeholder="Referral/Discount Code" />          
              <Button type="button" onClick={async () => { const result = await trigger("discount"); }}>Check</Button>
          
          {/* {offer.length > 0 && ( */}
            <Typography>{offer}</Typography>
            <Typography>{offerState}</Typography>
          {/* )} */}
          <StepNav handleNext={handleSubmit(onSubmit)} />
        </form>
    </FormProvider>
  );
};

export default YourDetails;

对于解决 state 问题或如何将验证代码或验证响应代码移动到 function 正文中的任何建议,我将不胜感激。

将您的架构移动到 function 正文中:

const YourDetails = () => {
let offer = '';
const [offerState, setOfferState] = useState(0);

const schema = yup.object().shape({
  discount: yup.string().max(20).test('custom', null,
    function (value) {
      offer = '';
      setOfferState('');
      return new Promise((resolve, reject) => {
        const api = new ApiFacade();
        api.validateCode(value).then((result) => {
          if (result.hasFailed) {
            resolve(this.createError({ message: `Error checking code` }));
          } else {
            if (result.value.errorCode) {
              resolve(this.createError({ message: result.value.errorMessage }));
            } else {
              offer = result.value.offerDescription;
              setOfferState(result.value.offerDescription);
              resolve(true);
            }
          }
      })
    })
});

  const formApi = useForm({
    resolver: yupResolver(schema)
  });

  const { handleSubmit, setValue, trigger } = formApi;

  return (
    <FormProvider {...formApi}>

        <form onSubmit={handleSubmit(onSubmit)}>
          
              <Input name="discount" placeholder="Referral/Discount Code" />          
              <Button type="button" onClick={async () => { const result = await trigger("discount"); }}>Check</Button>
          
          {/* {offer.length > 0 && ( */}
            <Typography>{offer}</Typography>
            <Typography>{offerState}</Typography>
          {/* )} */}
          <StepNav handleNext={handleSubmit(onSubmit)} />
        </form>
    </FormProvider>
  );
};

export default YourDetails;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM