Как использовать html-react-parser для добавления значений в state?

Как исправить проблему с бесконечным ререндером при использовании библиотеки html-react-parser для поиска элементов с тегом data-type: 'value' и добавлении соответствующего значения в state? Приведенный ниже код начинает бесконечно ререндериться.

Пример кода:

```javascript
const Component: React.FC<any> = ({ html }) => {
  const [data, setData] = useState<number[]>([])

  const replaceNode = (domNode: any) => {
    if (domNode.attribs && domNode.attribs['data-type'] && domNode.attribs['data-type'] === 'value') {
      setData((prevState) => [...prevState, 12])
    }

    return (
      <Box></Box>
    )
  }

  const options = {
    replace: replaceNode,
  }

  return (
    <Box sx={{ maxWidth: '100vw' }}>
      {parse(html, options)}
    </Box>
  )
}

export default Component
```
  • 25 октября 2023 г. 9:48
Ответы на вопрос 1
Проблема возникает из-за того, что каждый раз при вызове replaceNode функция добавляет новое значение в стейт, что приводит к ререндеру компонента и вызову функции заново.

Чтобы исправить эту проблему, можно изменить логику использования стейта внутри replaceNode функции. Вместо того, чтобы использовать setData для добавления значения в стейт, можно сохранить все значения в локальную переменную и добавить их в стейт однократно после завершения парсинга.

Вот исправленный код:

```javascript
const Component: React.FC<any> = ({ html }) => {
  const [data, setData] = useState<number[]>([])

  useEffect(() => {
    const newData: number[] = []

    const replaceNode = (domNode: any) => {
      if (domNode.attribs && domNode.attribs['data-type'] && domNode.attribs['data-type'] === 'value') {
        newData.push(12)
      }

      return (
        <Box></Box>
      )
    }

    const options = {
      replace: replaceNode,
    }

    parse(html, options)

    setData((prevState) => [...prevState, ...newData])
  }, [html])

  return (
    <Box sx={{ maxWidth: '100vw' }}>
      {/* Вывод значений из стейта */}
      {data.map((value, index) => (
        <span key={index}>{value}</span>
      ))}
    </Box>
  )
}

export default Component
```

В данном случае использован хук useEffect для выполнения функции replaceNode однократно после загрузки компонента и при изменении значения html. Значения, полученные внутри replaceNode, сохраняются в локальной переменной newData. После завершения парсинга, весь newData добавляется в стейт с помощью setData.

Теперь значений будет только одно добавление в стейт, а не по одному на каждый ререндер компонента.
Похожие вопросы