将选定值传递给 Get 请求
Pass Selected Values to a Get request
我的目标是将表单中选择的值传递给 get
请求。
请求应如下所示,在 values
的 submit
之后。
get(api/csv/pets/?columns=DOG&columns=CAT&columns=FISH)
onSubmit={async (values, { resetForm }) => {
alert(JSON.stringify(values, null, 2));
setCsvData(values);
console.log(csvData);
const getCsvFile = async (values) => {
try {
const { data } = await fetchContext.authAxios.get(
`/api/csv/pets/${id}/?columns=${csvData ? csvData + '&' : null}`, values);
toCsv(data);
} catch (err) {
console.log(err);
}
};
getCsvFile();
然而,即使 formik 接受了一个值的有效负载,当我将它放在 csvData
和 setCsvData(values)
中时我仍然得到未定义。
如何获取查询中选择的值,并采用所需的格式?
我的数据:
export const CheckList = [
{
id: 'column-dog',
label: 'Dog',
value: 'DOG',
name: 'column',
},
{
id: 'column-cat',
label: 'Cat',
value: 'CAT',
name: 'column',
},
{
id: 'column-turtle',
label: 'Turtle',
value: 'TURTLE',
name: 'column',
},
{
id: 'column-fish',
label: 'Fish',
value: 'FISH',
name: 'column',
},
]
我的表格:
const [csvData, setCsvData] = useState([]);
const selectAllData = CheckList.map((checkbox) => checkbox.value);
return (
<Formik
initialValues={{
columns: [],
selectAll: false,
}}
onSubmit={async (values, { resetForm }) => {
alert(JSON.stringify(values, null, 2));
setCsvData(values);
console.log(csvData);
resetForm();
}}
>
{({ values, setFieldValue }) => (
<Form>
<div>
<Field
onChange={() => {
if (!values.selectAll) {
setFieldValue('columns', selectAllData);
} else {
setFieldValue('columns', []);
}
setFieldValue('selectAll', !values.selectAll);
}}
checked={values.selectAll}
type="checkbox"
name="selectAll"
/>{' '}
Select All
</div>
{CheckList.map((checkbox) => (
<div key={checkbox.value}>
<label>
<Field
type="checkbox"
name="columns"
value={checkbox.value}
/>{' '}
{checkbox.label}
</label>
</div>
))}
<button
className="btn"
type="submit"
download
>
DOWNLOAD CSV
</button>
</Form>
)}
</Formik>
)
您不能在异步函数中使用 setState,因为 setState 本身就是一个异步函数,它不是 return 承诺。因此,我们不能将 async/await
用于 setState 方法。(如果不可能使其成为 await
,则状态更改将立即触发undefined
值而不是设置给定值)
更多信息请参考:https://iamsongcho.medium.com/is-setstate-async-b1947fbb25e5
因此,最好的用例是从 onSubmit()
函数中删除 async
以使其同步。因此,setState 将异步触发组件中的状态更改。
然后在表格重置后保留 getCsvFile(values)
,因为您已经这样做了。并将 getCsvFile()
函数保留在组件外部,因为它不会进行任何与状态相关的更改。
onSubmit={(values, { resetForm }) => {
alert(JSON.stringify(values, null, 2));
setCsvData(values);
console.log(csvData);
resetForm();
getCsvFile(); // this function will trigger asynchronously
}}
我认为您的代码过于复杂了。从状态中删除 csvData
,而是将 values
传递到请求中。
onSubmit={async (values, { resetForm }) => {
const getCsvFile = async () => {
try {
const { data } = await fetchContext.authAxios.get(
`/api/csv/pets/${id}/?columns=${values ? values + '&' : null}`, values);
toCsv(data);
} catch (err) {
console.log(err);
}
};
getCsvFile();
}
您遇到错误是因为请求在 csvData
设置之前触发。 setState
是异步的:)
我的目标是将表单中选择的值传递给 get
请求。
请求应如下所示,在 values
的 submit
之后。
get(api/csv/pets/?columns=DOG&columns=CAT&columns=FISH)
onSubmit={async (values, { resetForm }) => {
alert(JSON.stringify(values, null, 2));
setCsvData(values);
console.log(csvData);
const getCsvFile = async (values) => {
try {
const { data } = await fetchContext.authAxios.get(
`/api/csv/pets/${id}/?columns=${csvData ? csvData + '&' : null}`, values);
toCsv(data);
} catch (err) {
console.log(err);
}
};
getCsvFile();
然而,即使 formik 接受了一个值的有效负载,当我将它放在 csvData
和 setCsvData(values)
中时我仍然得到未定义。
如何获取查询中选择的值,并采用所需的格式?
我的数据:
export const CheckList = [
{
id: 'column-dog',
label: 'Dog',
value: 'DOG',
name: 'column',
},
{
id: 'column-cat',
label: 'Cat',
value: 'CAT',
name: 'column',
},
{
id: 'column-turtle',
label: 'Turtle',
value: 'TURTLE',
name: 'column',
},
{
id: 'column-fish',
label: 'Fish',
value: 'FISH',
name: 'column',
},
]
我的表格:
const [csvData, setCsvData] = useState([]);
const selectAllData = CheckList.map((checkbox) => checkbox.value);
return (
<Formik
initialValues={{
columns: [],
selectAll: false,
}}
onSubmit={async (values, { resetForm }) => {
alert(JSON.stringify(values, null, 2));
setCsvData(values);
console.log(csvData);
resetForm();
}}
>
{({ values, setFieldValue }) => (
<Form>
<div>
<Field
onChange={() => {
if (!values.selectAll) {
setFieldValue('columns', selectAllData);
} else {
setFieldValue('columns', []);
}
setFieldValue('selectAll', !values.selectAll);
}}
checked={values.selectAll}
type="checkbox"
name="selectAll"
/>{' '}
Select All
</div>
{CheckList.map((checkbox) => (
<div key={checkbox.value}>
<label>
<Field
type="checkbox"
name="columns"
value={checkbox.value}
/>{' '}
{checkbox.label}
</label>
</div>
))}
<button
className="btn"
type="submit"
download
>
DOWNLOAD CSV
</button>
</Form>
)}
</Formik>
)
您不能在异步函数中使用 setState,因为 setState 本身就是一个异步函数,它不是 return 承诺。因此,我们不能将 async/await
用于 setState 方法。(如果不可能使其成为 await
,则状态更改将立即触发undefined
值而不是设置给定值)
更多信息请参考:https://iamsongcho.medium.com/is-setstate-async-b1947fbb25e5
因此,最好的用例是从 onSubmit()
函数中删除 async
以使其同步。因此,setState 将异步触发组件中的状态更改。
然后在表格重置后保留 getCsvFile(values)
,因为您已经这样做了。并将 getCsvFile()
函数保留在组件外部,因为它不会进行任何与状态相关的更改。
onSubmit={(values, { resetForm }) => {
alert(JSON.stringify(values, null, 2));
setCsvData(values);
console.log(csvData);
resetForm();
getCsvFile(); // this function will trigger asynchronously
}}
我认为您的代码过于复杂了。从状态中删除 csvData
,而是将 values
传递到请求中。
onSubmit={async (values, { resetForm }) => {
const getCsvFile = async () => {
try {
const { data } = await fetchContext.authAxios.get(
`/api/csv/pets/${id}/?columns=${values ? values + '&' : null}`, values);
toCsv(data);
} catch (err) {
console.log(err);
}
};
getCsvFile();
}
您遇到错误是因为请求在 csvData
设置之前触发。 setState
是异步的:)