2

Formik と React Native は初めてです。現在、私の目標は、ナビゲーション ヘッダーを介してフォームを送信することです。私が見つけたすべての例は、画面ページ自体からフォームを送信することです。handleSubmitおよびonSubmitプロパティとsetParamsを適切に使用して値をナビゲーション ヘッダーに適切に渡す方法を理解する助けが必要です。

現在、フォームから useCallBack フックに値を送信しないことで立ち往生しています。

import React, {useState, useEffect, useCallback} from 'react';
import {StyleSheet, View, Button, Text} from 'react-native';
import {Input} from 'react-native-elements';
import {useDispatch} from 'react-redux';
import Colors from '../../constants/Colors';
import {
  HeaderButtons,
  HeaderButton,
  Item,
} from 'react-navigation-header-buttons';
import {Ionicons} from '@expo/vector-icons';
import {CommonActions} from '@react-navigation/native';
import * as prodActions from '../../store/actions/products';
import {Formik} from 'formik';
import * as Yup from 'yup';

const AddProduct = ({navigation}) => {

  const dispatch = useDispatch();

  const submitHandler = useCallback(() => {
    dispatch(prodActions.addProduct(value));
  }, [value]);

  useEffect(() => {
    navigation.dispatch(CommonActions.setParams({submitForm: submitHandler}));
  }, [submitHandler]);

  return (
    <View style={styles.screen}>
      <Formik
        initialValues={{title: '', description: '', imageUrl: ''}}
        validationSchema={Yup.object({
          title: Yup.string().required('please input your title'),
          description: Yup.string().required('please input your description'),
          imageUrl: Yup.string()
            //.email('Please input a valid email.')
            .required('Please input an email address.'),
        })}
        onSubmit={submitHandler}
      >
        {({
          handleChange,
          handleBlur,
          handleSubmit,
          values,
          touched,
          errors,
        }) => (
          <View>
            <Input
              label="Title"
              labelStyle={{color: Colors.accent}}
              onChangeText={handleChange('title')}
              onBlur={handleBlur('title')}
              value={values.title}
              // errorMessage={errors.title}
            />
            {touched.title && errors.title ? (
              <Text style={styles.error}>{errors.title}</Text>
            ) : null}
            <Input
              label="Description"
              labelStyle={{color: Colors.accent}}
              onChangeText={handleChange('description')}
              onBlur={handleBlur('description')}
              value={values.description}
            />
            {touched.description && errors.description ? (
              <Text style={styles.error}>{errors.description}</Text>
            ) : null}
            <Input
              label="Image URL"
              labelStyle={{color: Colors.accent}}
              onChangeText={handleChange('imageUrl')}
              onBlur={handleBlur('imageUrl')}
              value={values.imageUrl}
            />
            {touched.imageUrl && errors.imageUrl ? (
              <Text style={styles.error}>{errors.imageUrl}</Text>
            ) : null}
            <Button onPress={handleSubmit} title="Submit" />
          </View>
        )}
      </Formik>
    </View>
  );
};

const IoniconsHeaderButton = (props) => (
  <HeaderButton
    IconComponent={Ionicons}
    iconSize={23}
    color="white"
    {...props}
  />
);

export const AddProductHeaderOptions = (navData) => {
  const updateForm = navData.route.params.submitForm;
  return {
    headerRight: () => {
      return (
        <HeaderButtons HeaderButtonComponent={IoniconsHeaderButton}>
          <Item title="add" iconName="save-outline" onPress={updateForm} />
        </HeaderButtons>
      );
    },
  };
};

export default AddProduct;

const styles = StyleSheet.create({
  screen: {
    flex: 1,
    marginHorizontal: 20,
    marginTop: 20,
  },
  error: {
    marginLeft: 8,
    fontSize: 14,
    color: 'red',
  },
});
4

3 に答える 3