Javascript 从函数体外部调用React setState

Javascript 从函数体外部调用React setState,javascript,reactjs,Javascript,Reactjs,我是一个新手,我正在尝试让一些动态内容基于对API的调用来验证一些输入数据 由于我使用yup验证的方式,我认为处理API调用响应的代码必须在react函数体之外。这意味着我不能使用“setOfferState”,如下面的示例所示 我试着只使用一个基本变量“offer”来实现这一点,大多数情况下这似乎都可以,但我不相信这会一直起作用,因为我有时会在控制台中出错,不得不重新加载页面。我知道这不是在React中设置变量的正确方法 下面的示例中显示了offer和offerState,但offerStat

我是一个新手,我正在尝试让一些动态内容基于对API的调用来验证一些输入数据

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

我试着只使用一个基本变量“offer”来实现这一点,大多数情况下这似乎都可以,但我不相信这会一直起作用,因为我有时会在控制台中出错,不得不重新加载页面。我知道这不是在React中设置变量的正确方法

下面的示例中显示了offer和offerState,但offerState不起作用(错误:钩子调用无效。钩子只能在函数组件的主体内部调用。)


让报价='';
常量[offerState,setOfferState]=使用状态(0);
const schema=yup.object().shape({
折扣:yup.string().max(20).test('custom',null,
函数(值){
报价=“”;
setOfferState(“”);
返回新承诺((解决、拒绝)=>{
const api=新的apifeacade();
api.validateCode(值)。然后((结果)=>{
offer=result.value.offerDescription;
setOfferState(result.value.offerDescription);
})
})
})
});
const YourDetails=()=>{
const formApi=useForm({
解析程序:yupResolver(架构)
});
const{handleSubmit,setValue,trigger}=formApi;
返回(
{const result=等待触发器(“折扣”);}>检查
{/*{offer.length>0&(*/}
{offer}
{offerState}
{/* )} */}
);
};
导出默认的详细信息;

如果有任何建议可以解决状态问题,或者如何将验证代码或验证响应代码移到函数体中,我将不胜感激。

将您的模式移到函数体中:

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;
constYourDetails=()=>{
让报价='';
常量[offerState,setOfferState]=使用状态(0);
const schema=yup.object().shape({
折扣:yup.string().max(20).test('custom',null,
函数(值){
报价=“”;
setOfferState(“”);
返回新承诺((解决、拒绝)=>{
const api=新的apifeacade();
api.validateCode(值)。然后((结果)=>{
if(result.hasfiled){
解析(this.createError({message:`Error checking code`}));
}否则{
if(result.value.errorCode){
解析(this.createError({message:result.value.errorMessage}));
}否则{
offer=result.value.offerDescription;
setOfferState(result.value.offerDescription);
决心(正确);
}
}
})
})
});
const formApi=useForm({
解析程序:yupResolver(架构)
});
const{handleSubmit,setValue,trigger}=formApi;
返回(
{const result=等待触发器(“折扣”);}>检查
{/*{offer.length>0&(*/}
{offer}
{offerState}
{/* )} */}
);
};
导出默认的详细信息;

将模式移动到函数体中:

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;
constYourDetails=()=>{
让报价='';
常量[offerState,setOfferState]=使用状态(0);
const schema=yup.object().shape({
折扣:yup.string().max(20).test('custom',null,
函数(值){
报价=“”;
setOfferState(“”);
返回新承诺((解决、拒绝)=>{
const api=新的apifeacade();
api.validateCode(值)。然后((结果)=>{
if(result.hasfiled){
解析(this.createError({message:`Error checking code`}));
}否则{
if(result.value.errorCode){
解析(this.createError({message:result.value.errorMessage}));
}否则{
offer=result.value.offerDescription;
setOfferState(result.value.offerDescription);
决心(正确);
}
}
})
})
});
const formApi=useForm({
解析程序:yupResolver(架构)
});
const{handleSubmit,setValue,trigger}=formApi;
返回(
{const result=等待触发器(“折扣”);}>检查
{/*{offer.length>0&(*/}
{offer}
{offerState}
{/* )} */}
);
};
导出默认的详细信息;

为什么要在yup验证器中执行所有这些操作?您也没有拒绝或解决承诺,因此验证将永远运行。与其描述您遇到的问题,不如描述您正在尝试完成的任务,因为您显示的代码即使稍加调整也无法可靠地工作。我添加了提供代码v验证。Yup已经被用于验证其他字段,因此似乎是一个很好的地方。此外,我在为这篇文章删减它时错过了解析位,现在我已经将它们添加回了。为什么你要在Yup验证程序中执行所有这些操作?你也没有拒绝或解析承诺,因此验证将永远运行。Inst在描述您遇到的问题之前,请描述您正试图完成的任务,因为您正在显示的代码即使稍作调整也无法可靠地工作。我正在添加提供的代码验证。Yup已用于验证其他字段,因此似乎是一个很好的位置。此外,在缩减代码时,我遗漏了解析位对于这篇文章,我现在又添加了它们。谢谢你,这么简单!出于某种原因,我认为它需要在它之外,Yup才能工作。谢谢你,这么简单!出于某种原因,我认为它需要在它之外,Yup才能工作。