У меня есть компонент, который содержит форму и список. Когда пользователь добавляет элемент в список через форму, элемент должен немедленно отображаться в списке. Я пытаюсь использовать useEffect для получения данных, useEffect без зависимости вызывает бесконечный цикл запроса. Я добавил пустой массив в качестве зависимости, чтобы предотвратить зацикливание, но в этом случае новый добавленный элемент не отображается в списке до обновления страницы. Как я могу решить эту проблему? (Я использую antd и antd-form-builder для создания компонента)
вот мой код:
function FieldSetting() {
const [form] = Form.useForm()
const [typeValue, setTypeValue] = useState()
const meta = {
fields: [{ key: "pathname", onChange: (e) => setTypeValue(e.target.value) }],
}
const [data, setData] = useState([])
async function onFinish() {
try {
await axios.post("api", { typeValue, typeId })
form.resetFields()
} catch (e) {
console.info(e)
}
}
useEffect(() => {
const getData = async () => {
const response = await fetch(`api?id=${typeId}`)
const newData = await response.json()
setData(newData)
}
getData()
}, [])
return (
<Container>
<Form form = {form} layout = "inline" className = "form-field" onFinish = {onFinish}>
<FormBuilder form = {form} meta = {meta} />
<Form.Item>
<Button type = "primary" htmlType = "submit">
Add
</Button>
</Form.Item>
</Form>
<div
id = "scrollableDiv"
style = {{
height: 665,
overflow: "auto",
padding: "0 16px",
border: "1px solid rgba(140, 140, 140, 0.35)",
}}
>
<List
itemLayout = "horizontal"
dataSource = {data}
renderItem = {(item) => (
<List.Item
actions = {[
<a key = "list-edit">edit</a>,
<a onClick = {() => axios.delete(`http://gage.axaneh.com/api/Gages/SettingProduct/RemoveProductSetting/${item.id}`, item)} key = "list-delete">
delete
</a>,
]}
>
<List.Item.Meta title = {item.typeValue} />
</List.Item>
)}
/>
</div>
</Container>
)
}
export default FieldSetting
Всякий раз, когда вы манипулируете своим массивом, просто добавьте фиктивное состояние и измените его.
добавить это состояние
const [extra, setExtra] = useState(0)
когда вы меняете состояние своего массива, например, добавляете или удаляете, просто добавьте эту строку ниже
setExtra(extra+1)
что происходит, так это то, что добавление или удаление данных в массиве не считается изменением состояния в реакции, насколько я понимаю, это должно быть что-то другое, например, от истинного до ложного или в этом случае от 0 до 1
Просто добавьте состояние, которое будет обновляться (активировать useEffect) после отправки формы. Имейте в виду, что он будет обновлять все данные из API. Это может привести к проблемам с масштабируемостью при увеличении объема данных.
function FieldSetting() {
const [form] = Form.useForm()
const [refetch, setRefetch] = useState(false) // <----- add this state
const [typeValue, setTypeValue] = useState()
const meta = {
fields: [{ key: "pathname", onChange: (e) => setTypeValue(e.target.value) }],
}
const [data, setData] = useState([])
async function onFinish() {
try {
await axios.post("api", { typeValue, typeId })
form.resetFields()
setRefetch(!refetch) // <----- set the refetch to change the state
} catch (e) {
console.info(e)
}
}
useEffect(() => {
const getData = async () => {
const response = await fetch(`api?id=${typeId}`)
const newData = await response.json()
setData(newData)
}
getData()
}, [refetch]) // <----- add the refetch here to trigger the effect
return (
<Container>
<Form form = {form} layout = "inline" className = "form-field" onFinish = {onFinish}>
<FormBuilder form = {form} meta = {meta}
/>
<Form.Item>
<Button type = "primary" htmlType = "submit">
Add
</Button>
</Form.Item>
</Form>
<div
id = "scrollableDiv"
style = {{
height: 665,
overflow: "auto",
padding: "0 16px",
border: "1px solid rgba(140, 140, 140, 0.35)",
}}
>
<List
itemLayout = "horizontal"
dataSource = {data}
renderItem = {(item) => (
<List.Item
actions = {[
<a key = "list-edit">edit</a>,
<a onClick = {() => axios.delete(`http://gage.axaneh.com/api/Gages/SettingProduct/RemoveProductSetting/${item.id}`, item)} key = "list-delete">
delete
</a>,
]}
>
<List.Item.Meta title = {item.typeValue} />
</List.Item>
)}
/>
</div>
</Container>
)
}
export default FieldSetting```
Спасибо Али за помощь. Моя проблема была решена вашим решением. Но теперь я столкнулся с другой проблемой: удаление элемента не отображает изменения в списке. Я добавил setRefetch(!refetch)
в функцию удаления onClick, чтобы активировать useEffect и отображать новый список сразу после удаления элемента, но это не работает. Как я могу решить эту проблему?
Я не вижу
setData
наonFinish
после добавления или удаления элемента