UseEffect не выполняет повторную визуализацию при изменении состояния или проблеме с бесконечным циклом

У меня есть компонент, который содержит форму и список. Когда пользователь добавляет элемент в список через форму, элемент должен немедленно отображаться в списке. Я пытаюсь использовать 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

Я не вижу setData на onFinish после добавления или удаления элемента

Azzy 02.01.2023 17:14
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
1
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Всякий раз, когда вы манипулируете своим массивом, просто добавьте фиктивное состояние и измените его.

добавить это состояние

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 и отображать новый список сразу после удаления элемента, но это не работает. Как я могу решить эту проблему?

Andish 03.01.2023 10:22

Другие вопросы по теме