简体   繁体   中英

How to persist formik form values if navigate to other screen in React Native

I am working on app where I am using formik form, it working fine but I face one issue when I open camera and take a picture when get back the form filled lost . I want to keep all values persist if I open camera etc . I really tried hard but didn't find any solution . Could someone please help me how to resolve this issue.

Thanks

    <Form
      initialValues={{ username: "", email: '' }}
      onSubmit={handleSubmit}
      key={Math.random()}
    >
    
      <FormField
        autoCapitalize="none"
        autoCorrect={false}
        icon="account"
        keyboardType="email-address"
        name="username"
        placeholder="Username"
        textContentType="emailAddress"
        maxLength={20}
        style={{ width: "100%" }}
      />
    
      <ListItemSeparator />
    
      <View style={{ marginVertical: 20 }}>
        <>
          <MaterialCommunityIcons name="camera" size={40} color="#666" onPress={() => cameraToggle(true)} />
    
          <Image resizeMode="cover" source={{ uri: camerBinaryImage && camerBinaryImage.uri }} style={{ height: Object.keys(camerBinaryImage).length > 0 ? 300 : 0, width: Object.keys(camerBinaryImage).length > 0 ? 300 : 0 }} />
        </>
      </View>
    
    
      <ListItemSeparator />
      <AppText style={styles.slugTitle}>Email</AppText>
    
      <ListItemSeparator />
      <FormField
        autoCapitalize="none"
        autoCorrect={false}
        keyboardType="email-address"
        comment={true}
        name="email"
        placeholder="Email"
        textContentType="emailAddress"
        style={{ width: "100%" }}
      />
    
    </Form>

If you can imagine it, you can program it. Maybe this will help you friend.

You must first install asynstorage . Now create a hook called useAsyncStorage.js and add the following code

 /* Librarys*/ import AsyncStorage from '@react-native-async-storage/async-storage'; const storeData = async (key, value) => { try { return await AsyncStorage.setItem(key, value); } catch (error) { console.log(error) } }, getData = async (key) => { try { let data = await AsyncStorage.getItem(key); return key !== null ? data : null; } catch (error) { console.log(error) } }, /* JSON */ storeDataJson = async (key, value) => { try { const jsonValue = JSON.stringify(value) await AsyncStorage.setItem(key, jsonValue) } catch (err) { console.log(err); } }, getDataJson = async key => { try { const jsonValue = await AsyncStorage.getItem(key); return jsonValue !== null ? JSON.parse(jsonValue) : null; } catch (err) { console.log(err); } } module.exports = { storeData, getData, storeDataJson, getDataJson }

Now an example to be able to use asynstorage with formik

 import React, { useEffect } from 'react'; import { TextInput } from 'react-native'; import { Formik, useFormik } from 'formik'; /* AsyncStorage */ import { storeData, getData } from './useAsyncStorage'; // your path const CustomComponent = () => { const initialValues = useFormik({ initialValues: { name: 'Husdady' } }) useEffect(() => { getData('keyname').then(savedValue => { console.log(savedValue) savedValue && initialValues.setFieldValue('name', savedValue); }) }, []); return ( <Formik initialValues={initialValues.values} enableReinitialize> {({ values, setFieldValue }) => { const { name } = values; console.log(values) return <TextInput value={name} placeholder="write something..." onChangeText={e => { setFieldValue('name', e); storeData('keyname', e); }} /> } } </Formik> ) } export default CustomComponent

First we are going to use the hook provided by formik: useFormik (). Now as parameters of that hook, we define an object with initial state properties.

We will also use the useEffect hook, when the component is rendered, we use the getData function of the useAsyncStorage hook to obtain the values ​​stored in async storage and then we use the setFieldValue method to change the value of the property set in the first parameter and in the second we change the value for which we have in the async storage.

Sorry if my English is bad. I am a Spanish speaker and I am using a translator

Formik has a helper: setValues.

This is an example from the React web, but I'm sure it also works for Native.

For example you could restore the values from local storage like @husdady explained. Not sure how Native does it, but you'll get the idea. You could also make a button "Save as draft" or you could save the draft in a effect hook when you leave the form, I demonstrate both cases below:

const { handleSubmit, handleChange, setValues, values } = useFormik({
  initialValues: {
    name: "",
    email: "",
  },
  onSubmit: (values) => {
    // Your submit logic
    console.log(values);
  }
});

const saveAsDraft = () => {
  // store the values in local storage
  localStorage.setItem('form', JSON.stringify(values));
}

React.useEffect(() => {
  // Get the Formik values from local storage and restore
  const storage = localStorage.getItem('form');

  if(storage) {
    setValues(JSON.parse(storage));
  }

  // On unmount (e.g. leave the page) save the values
  return () => {
    saveAsdraft();
  }
}, [])

return (
  <form onSubmit={handleSubmit}>
    <input
      name="name"
      value={values.name}
      onChange={handleChange}
    />
    <input
      name="email"
      value={values.email}
      onChange={handleChange}
    />
    <button type="submit">Submit</button>
    <button onClick={() => saveAsDraft()}>Save as draft</button>
  </form>
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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