You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中不使用useFormik时,如何在Formik组件外部调用handleSubmit并使用TouchableOpacity

在Formik组件外部调用handleSubmit的解决方案

嘿,这个问题很好解决!我们可以通过给Formik组件添加ref来获取它的实例,这样就能在组件外部调用提交方法了,完全不用换成useFormik Hook。具体实现步骤如下:

步骤说明

    1. 在组件类中创建一个React Ref,用来关联Formik组件实例
    1. 将这个Ref绑定到Formik组件上
    1. 外部的TouchableOpacity通过Ref调用Formik内置的submitForm方法,同时可以通过Ref获取表单的isValid和isSubmitting状态来控制按钮禁用逻辑

修改后的完整代码

_handleSubmit = (values) =>{
  const user = firebase.auth().currentUser.uid;
  if(user){
    const profileData = firebase.database().ref('kullaniciBilgiler/'+`${user}`);
    profileData.update({
      age:values.age,
      cinsiyet:values.cinsiyet,
      email:values.email,
      job:values.job,
      liveCity:values.liveCity,
      name:values.name,
      school:values.school,
      schoolLevel:values.schoolLevel,
      surname:values.surname,
    }).then(()=>console.log('işlem tamam usta'))
  }
  alert('başarılı dirim!');
}

constructor(props) {
  super(props);
  // 新增:创建Formik的引用
  this.formikRef = React.createRef();
  this.state = {
    fileUri: '',
    list: []
    // 你的其他原有状态...
  };
}

render() {
  return (
    <SafeAreaView style={styles.container} >
      <View style={styles.profilePhoto}>
        <TouchableOpacity onPress={this.selectFile} >
          <Image source={{ uri: this.state.fileUri }} style={styles.profPhoto} />
        </TouchableOpacity>
      </View>
      <View style={styles.profileDetails}>
        <View style={{flex:1, alignSelf:'center', justifyContent:'center'}}>
          <FlatList style={{width:'100%',}}
            data={this.state.list}
            keyExtractor={(item)=>item.key}
            renderItem={({item})=>{
              return(
                <Formik
                  // 新增:绑定ref到Formik组件
                  ref={this.formikRef}
                  initialValues={{ val : item.val }}
                  onSubmit={this._handleSubmit}
                  validationSchema={ Yup.object().shape({
                    val: Yup.string().required(<Text style={{ color: 'red' }}>basarısız {item.key}</Text>),
                  }) }
                >
                  { ({ values, isValid, isSubmitting, errors, handleChange }) => (
                    <View style={{flexDirection:'column', width:windowWidth, paddingHorizontal:20, paddingVertical:10}}>
                      <Text style={styles.ppText}>{item.key}</Text>
                      <TextInput defaultValue={item.val} style={styles.input} onChangeText={handleChange('val')} ></TextInput>
                      {(errors.val) && <Text>{errors.val}</Text>}
                      {/* 移除内部的提交按钮 */}
                    </View>
                  ) }
                </Formik>
              )
            }}/>
        </View>
        {/* 外部的提交按钮 */}
        <TouchableOpacity 
          disabled={!this.formikRef.current?.isValid || this.formikRef.current?.isSubmitting}
          onPress={() => {
            // 通过ref调用Formik的提交方法
            if (this.formikRef.current) {
              this.formikRef.current.submitForm();
            }
          }} 
        >
          <Text style={{textAlign:'center'}}>GÜNCELLE</Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  )
}

补充说明

  • 这里用了可选链操作符?.来避免formikRef.current为null时的报错,如果你需要兼容更低版本的React Native,可以换成条件判断:this.formikRef.current && this.formikRef.current.isValid
  • 如果你在FlatList里渲染了多个Formik组件,那单个ref就不够用了,这种情况需要创建一个ref数组,给每个Formik绑定对应的索引ref,然后批量处理提交逻辑

内容的提问来源于stack exchange,提问作者Turan Bicav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 17:07:32