【问题标题】:Adding new object to an array in React Native在 React Native 中向数组添加新对象
【发布时间】:2021-01-16 23:35:28
【问题描述】:

我创建了一个表单来在主屏幕上上传图像和文本字段,但我面临一个问题,即它没有更新数组并且因此验证失败。我认为我的实现有问题

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>

这是我的表单域,我想一切都在这里

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)}
              />
            </>

我认为 addPost 方法有问题,因为我之前使用函数库做过,那次我只将文本添加到列表中并且它工作但在类库中我不知道这样做我只是尝试与我相同的方式在函数库中做了

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>
    );
  }
}


提交后

【问题讨论】:

    标签: javascript reactjs react-native expo react-native-flatlist


    【解决方案1】:

    我假设你的 addPost 函数逻辑是错误的,

    试试下面的代码

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

    如果您遇到同样的错误,请告诉我。

    【讨论】:

    • thnx 我会试试看,你能告诉我如何使用 formik 和 yup 验证图像吗?
    【解决方案2】:

    您没有将图像更新为 formik,因此您会收到所需的错误是正常的。 首先在您的 AddPost 组件中将 formikProps 传递给 FormImage 组件。

    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>
    

    在 FormImage 中使用该 formikProps 并调用 setFieldValue("image", result.uri) 来更新图像的 formik 值。

    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>
        );
      }
    }
    
    

    在家里

    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();
      };
    

    【讨论】:

    • 非常感谢,我从昨天开始一直在寻找,我的 addPost 方法在 home.js 中是否正确?
    • 同样的行为?你看到了什么
    • 只是重置文本输入值然后什么都没有发生,表单仍然保持打开状态,图像仍然显示在表单中,等等让我添加它的截图
    • 我在我的问题中添加了图片检查它
    • 它成功了,非常感谢你的帮助,在你的代码中稍微更正它不是....prevPost.posts它是....prevPost.post
    猜你喜欢
    • 1970-01-01
    • 2020-08-09
    • 2021-04-05
    • 2019-03-03
    • 2020-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-28
    相关资源
    最近更新 更多