Reactjs Formik、Material UI Autocomplete和Firestore-在何处查询以查找数组参数
如何修改formik onChange处理程序,使其仅保存传递给Material UI Autocomplete字段的选项的值(而不是值加标签的数组) 我有一个集合,它有一个名为category属性的文档。当前,该类别将使用表单条目选项中的标签和值填充 我正在努力找到一种方法来获取firebase where查询,以查找数组的value属性 我想知道如果我尝试只保存值,而不是将标签和值都保存到firestore中,是否可以更接近一个有效的解决方案 我有一份Formik表格,上面有:Reactjs Formik、Material UI Autocomplete和Firestore-在何处查询以查找数组参数,reactjs,firebase,google-cloud-firestore,material-ui,formik,Reactjs,Firebase,Google Cloud Firestore,Material Ui,Formik,如何修改formik onChange处理程序,使其仅保存传递给Material UI Autocomplete字段的选项的值(而不是值加标签的数组) 我有一个集合,它有一个名为category属性的文档。当前,该类别将使用表单条目选项中的标签和值填充 我正在努力找到一种方法来获取firebase where查询,以查找数组的value属性 我想知道如果我尝试只保存值,而不是将标签和值都保存到firestore中,是否可以更接近一个有效的解决方案 我有一份Formik表格,上面有: impor
import React, { useState } from "react";
import ReactDOM from "react-dom";
import {render} from 'react-dom';
import { Link } from 'react-router-dom';
import firebase, {firestore} from '../../../firebase';
import { withStyles } from '@material-ui/core/styles';
import {
Button,
LinearProgress,
MenuItem,
FormControl,
Divider,
InputLabel,
FormControlLabel,
TextField,
Typography,
Box,
Grid,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
} from '@material-ui/core';
import MuiTextField from '@material-ui/core/TextField';
import {
Formik, Form, Field, ErrorMessage, FieldArray,
} from 'formik';
import * as Yup from 'yup';
import {
Autocomplete,
ToggleButtonGroup,
AutocompleteRenderInputParams,
} from 'formik-material-ui-lab';
import {
fieldToTextField,
TextFieldProps,
Select,
Switch,
CheckboxWithLabel,
Checkbox
} from 'formik-material-ui';
const allCategories = [
{value: 'health', label: 'Health & Medical'},
{value: 'general', label: 'General'},
];
function UpperCasingTextField(props: TextFieldProps) {
const {
form: {setFieldValue},
field: {name},
} = props;
const onChange = React.useCallback(
event => {
const {value} = event.target;
setFieldValue(name, value ? value.toUpperCase() : '');
},
[setFieldValue, name]
);
return <MuiTextField {...fieldToTextField(props)} onChange={onChange} />;
}
function Summary(props) {
const { classes } = props;
const [open, setOpen] = useState(false);
const [isSubmitionCompleted, setSubmitionCompleted] = useState(false);
function handleClose() {
setOpen(false);
}
function handleClickOpen() {
setSubmitionCompleted(false);
setOpen(true);
}
return (
<React.Fragment>
<Button
// component="button"
color="primary"
onClick={handleClickOpen}
style={{ float: "right"}}
variant="outlined"
>
Create
</Button>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="form-dialog-title"
>
{!isSubmitionCompleted &&
<React.Fragment>
<DialogContent>
<Formik
initialValues={{ title: "", category: [], subcategory: "" }}
onSubmit={(values, { setSubmitting }) => {
setSubmitting(true);
firestore.collection("study").doc().set({
...values,
createdAt: firebase.firestore.FieldValue.serverTimestamp()
})
.then(() => {
setSubmitionCompleted(true);
});
}}
validationSchema={Yup.object().shape({
title: Yup.string()
.required('Required'),
category: Yup.string()
.required('Required'),
})}
>
{(props) => {
const {
values,
touched,
errors,
dirty,
isSubmitting,
handleChange,
handleBlur,
handleSubmit,
handleReset,
} = props;
return (
<form onSubmit={handleSubmit}>
<TextField
label="Title"
name="title"
// className={classes.textField}
value={values.title}
onChange={handleChange}
onBlur={handleBlur}
helperText={(errors.title && touched.title) && errors.title}
margin="normal"
style={{ width: "100%"}}
/>
<Box margin={1}>
<Field
name="category"
multiple
component={Autocomplete}
options={allCategories}
// value={values.label}
// value={values.value}
// value={allCategories.value}
// value={values.category.allCategories.value}
注意-此操作用于查找标题。标题字段位于同一位置
级别作为类别字段
我已经看到了,但我不够聪明,无法从答案中理解任何意义
我也看到了贝蒂建议的答案。我尝试了以下查询构造的多个变体来尝试使用这个想法,但是每次,我都会在查询的形式上出错
.where(new firebase.firestore().FieldPath("category", "value"), '==', 'health')
我想知道我是否可以尝试在formik中获取category表单字段,只保存option.value而不是label和value
我看不出formik handleChange如何要求它只保存价值
即使这样,我也看不到如何查询firestore以使用数组的内容作为查询参数
有谁知道:
.where("category", "array-contains", {value: "health", label: "Health & Medical"})
答案强调了将整个数组内容添加到大括号中的重要性。这很有效
所以-这让我回到自动完成提交处理程序。这是一个多选字段,因此可能会选择多个值。如何在firebase文档中将这些值转换为一组单个值。即使只有一个,如何更改提交处理程序,使其只发送select选项值,而不发送值和标签
如果无法查询数组中的对象-如何更改提交处理程序以仅向firebase添加选定选项值,而不是同时添加标签和值?第一个答案中建议的解决方法是添加一个字段,该字段仅包含要查询的值(so:health)。我将通过逐一回答您的问题来澄清您的疑问
- 为了只保存
,您需要更改向Firestore发送信息的方式。更改值
变量,因为此变量同时维护值
中的值。总之,在与Firestore相关时,您需要基本上更改代码,在Firestore中,您可以使用标签
值创建变量标签
- 澄清你提到的这篇文章——通常NoSQL数据库是按照你将要查询的方式创建的。因此,您将首先根据需要对查询和数据库结构进行修改,这样您就不会遇到任何问题。由于无法在
数组中搜索对象,因此我认为重构方案是最佳选择
- 也许使用本例中阐明的子集合可以帮助您简化工作
更改是您的最佳选择,因此您可以拥有一个完全适合您的查询和需求的方案-这是NoSQL的许多好部分之一,可以自由创建方案。在提交给firebase之前,您可以在
onSubmit
中更改发送的数据的形状
onSubmit={(values, { setSubmitting }) => {
setSubmitting(true);
firestore.collection("study").doc().set({
...values,
category: values.category.map(c => c.value),
createdAt: firebase.firestore.FieldValue.serverTimestamp()
})
.then(() => {
setSubmitionCompleted(true);
});
}}
感谢您的注释@gso_gabirel。首先,关于自动完成的问题的原因是,如果我没有在表单元素中使用AllCategories数组,则选择菜单中显示的选项不会使用标签填充下拉列表。我找不到一个示例来说明如何只保存值,而不是同时保存标签和值。我在这个集合中没有子集合。我不知道你为什么认为我会。我有一个集合,其中包括一个名为category的属性。类别是一个数组。数组有一个名为“value”的属性,我正在尝试查询该属性。你的子集合常数
.where(new firebase.firestore().FieldPath("category", "value"), '==', 'health')
.where("category", "array-contains", {value: "health", label: "Health & Medical"})
onSubmit={(values, { setSubmitting }) => {
setSubmitting(true);
firestore.collection("study").doc().set({
...values,
category: values.category.map(c => c.value),
createdAt: firebase.firestore.FieldValue.serverTimestamp()
})
.then(() => {
setSubmitionCompleted(true);
});
}}