我想通过更改">select"元素来更改状态值。所以我在 onChange 处理程序中调用setFilter方法。但是状态没有得到更新。它保持以前的值。 如何解决这个问题?
我想通过更改">选择"元素来更改状态值。所以我在 onChange 处理程序中调用setFilter方法。但是状态没有得到更新。它保持以前的值。 如何解决这个问题?
import React, { useState, useEffect } from 'react'
import { useHistory } from 'react-router-dom'
import { useApolloClient} from 'react-apollo';
import { Formik, Form, ErrorMessage } from 'formik';
import * as Yup from "yup";
import AsyncPaginate from 'react-select-async-paginate'
import { GET_ITEM_CODES } from '../../library/Query';
export default function SampleForm({initialData}){
const history = useHistory();
const [productFilter, setProductFilter] = useState('');
const client = useApolloClient();
const defaultAdditional = {
cursor : null
}
const shouldLoadMore = (scrollHeight, clientHeight, scrollTop) => {
const bottomBorder = (scrollHeight - clientHeight) / 2
return bottomBorder < scrollTop
}
const loadItemcodeOptions = async (q = 0, prevOptions, {cursor}) => {
console.log('qu',q*1)
const options = [];
console.log('load')
const response = await client.query({
query:GET_ITEM_CODES,
variables : {filter: {
number_gte : q*1
},skip:0, first:4, after: cursor}
})
console.log('res',response)
response.data.itemCodes.itemCodes.map(item => {
return options.push({
value: item.number,
label: `${item.number} ${item.description}`
})
})
console.log('0',options)
return {
options,
hasMore: response.data.itemCodes.hasMore,
additional: {
cursor: response.data.itemCodes.cursor.toString()
}
}
}
const handleFilter = (e) => {
console.log('e',e)
setProductFilter(e.value)
console.log('pf',productFilter) // output is previous State(wrong)
}
useEffect(() => {
console.log('epf',productFilter) // output the current state(expected)
})
return(
<Formik
initialValues = {{
itemCode: !!initialData ? {value: initialData.itemCode, label: initialData.itemCode} : '',
}}
validationSchema = {Yup.object().shape({
itemCode: Yup.number().required('Required'),
})}
>
{({values, isSubmitting, setFieldValue, touched, errors }) => (
<Form>
<label htmlFor="itemCode">Item Code</label>
<AsyncPaginate
name="itemCode"
defaultOptions
debounceTimeout={300}
cacheOptions
additional={defaultAdditional}
value={values.itemCode}
loadOptions={loadItemcodeOptions}
onChange={option => {
handleFilter(option)
setFieldValue('itemCode', option)
}}
shouldLoadMore={shouldLoadMore}
/>
<ErrorMessage name="itemcode"/>
<pre>{JSON.stringify(values, null, 2)}</pre>
</Form>
)}
</Formik>
)
}
实际上setProductFilter
是异步设置状态的,因此您将在效果中获得更新的状态,而不是在调用 setState 后立即获得。但是每次重新渲染组件时,您的效果都会运行,因此您应该添加productFilter
作为useEffect
的依赖项。 我想提到的另一件事是,我不知道你的用例,但你应该坚持规则:单一事实来源。产品过滤器有两种状态,一种是 Formik,即 itemCode,另一种是本地状态。我认为您可以删除本地状态并从formikProps.values.itemCode
中使用项目代码.