0

I have created a form to upload the image and text field on the home screen but I am facing a problem that it's not updating the array and validation is failing due to that. I think something wrong with my implementation

AddPost.js

const validationSchema = Yup.object({
  title: Yup.string().required().min(5).max(15).label("Title"),
  des: Yup.string().required().min(15).max(200).label("Description"),
  image: Yup.array().required().label("Image"),
});

class AddPost extends Component {
  render() {
    return (
      <Formik
        initialValues={{ title: "", des: "", image: [] }}
        onSubmit={(values, actions) => {
          actions.resetForm();
          this.props.addPost(values);
        }}
        validationSchema={validationSchema}
      >
        {(value) => (
          <View>
            <FormImage />
            <Text style={styles.error}>
              {value.touched.image && value.errors.image}
            </Text>
            <TextInput
              placeholder="Title"
              onChangeText={value.handleChange("title")}
              style={styles.input}
              value={value.values.title}
              onBlur={value.handleBlur("title")}
            />
            <Text style={styles.error}>
              {value.touched.title && value.errors.title}
            </Text>

Here is my form field I think everything is right here

home.js

class Home extends Component {
  state = {
    modal: false,
    post: [
      {
        key: "1",
        title: "A Good Boi",
        des: "He's a good boi and every one know it.",
        image: require("../assets/dog.jpg"),
      },
      {
        key: "2",
        title: "John Cena",
        des: "As you can see, You can't see me!",
        image: require("../assets/cena.jpg"),
      },
    ],
    image: null,
  };


  addPost = (posts) => {
    posts.key = Math.random().toString();
    this.setState.post((currentPost) => {
      return [posts, ...currentPost];
    });
    this.state.modal();
  };

  render() {
    return (
      <Screen style={styles.screen}>
        <Modal visible={this.state.modal} animationType="slide">
          <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
            <View style={styles.modalContainer}>
              <AddPost addPost={() => this.addPost} />
            </View>
          </TouchableWithoutFeedback>
        </Modal>
        <FlatList
          data={this.state.post}
          renderItem={({ item }) => (
            <>
              <Card
                title={item.title}
                subTitle={item.des}
                image={item.image}
                onPress={() => this.props.navigation.navigate("Edit", item)}
              />
            </>

I think something wrong with the addPost method because I did it before with function base that time I only added text to the list and its worked but in class base I don't know to do it I just try the same way I did in function base

FormImage.js

class FormImage extends Component {
  state = {
    image: null,
    hasCameraPermission: null,
  };

  async componentDidMount() {
    const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
    this.setState({ hasCameraPermission: status === "granted" });
  }

  _pickImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      aspect: [4, 3],
    });

    if (!result.cancelled) {
      this.setState({ image: result.uri });
    }
  };

  render() {
    const { image } = this.state;
    return (
      <TouchableWithoutFeedback onPress={this._pickImage}>
        <View style={styles.container}>
          {!image && (
            <MaterialCommunityIcons
              color={colors.medium}
              name="camera"
              size={40}
            />
          )}
          {image && <Image style={styles.image} source={{ uri: image }} />}
        </View>
      </TouchableWithoutFeedback>
    );
  }
}


after submiting enter image description here

2 Answers 2

1

Iam assuming your addPost function logic is wrong,

Try the below code

 addPost = (posts) => {
    posts.key = Math.random().toString();
    this.setState((prevState) => {
      return {...prevState, post: [...prevState.post, ...posts] };
    });
    this.state.modal();
  };

Let me know incase you are getting the same error.

Sign up to request clarification or add additional context in comments.

1 Comment

thnx i will try it, can you tell me how validate a image with formik and yup?
0

You are not updating images to formik so is normal you get the required error. First in your AddPost Component pass down formikProps to FormImage component.

return (
      <Formik
        initialValues={{ title: "", des: "", image: [] }}
        onSubmit={(values, actions) => {
          // actions.resetForm(); --> comment this
          this.props.addPost(values);
        }}
        validationSchema={validationSchema}
      >
        {(value) => (
          <View>
            <FormImage formikProps={value}/>
            <Text style={styles.error}>
              {value.touched.image && value.errors.image}
            </Text>
            <TextInput
              placeholder="Title"
              onChangeText={value.handleChange("title")}
              style={styles.input}
              value={value.values.title}
              onBlur={value.handleBlur("title")}
            />
            <Text style={styles.error}>
              {value.touched.title && value.errors.title}
            </Text>

In FormImage use that formikProps and call setFieldValue("image", result.uri) to update formik value for image.

class FormImage extends Component {
  state = {
    image: null,
    hasCameraPermission: null,
  };

  async componentDidMount() {
    const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
    this.setState({ hasCameraPermission: status === "granted" });
  }

  _pickImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      aspect: [4, 3],
    });

    if (!result.cancelled) {
      this.setState({ image: result.uri });
      this.props.formikProps.setFieldValue("image", result.uri);
    }
  };

  render() {
    const { image } = this.state;
    return (
      <TouchableWithoutFeedback onPress={this._pickImage}>
        <View style={styles.container}>
          {!image && (
            <MaterialCommunityIcons
              color={colors.medium}
              name="camera"
              size={40}
            />
          )}
          {image && <Image style={styles.image} source={{ uri: image }} />}
        </View>
      </TouchableWithoutFeedback>
    );
  }
}

In home

addPost = (posts) => {
    console.log('add post');
    posts.key = Math.random().toString();
    this.setState((prevState) => {
      return {...prevState, post: [...prevState.post, ...posts], modal: 
      true };
    });
    // this.state.modal();
  };

10 Comments

thank you so much i was searching for that from yesterday and is my addPost method is correct in home.js?
same behaviour? what do you see
it's just reset text input value and then nothing happen, form still remain opened, image still showing in form, wait let me add screenshot of it
I added pic in my question check it
it worked thank you so much for help, a little correction in your code it's not ....prevPost.posts it's ....prevPost.post
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.