React. как корректно хранить состояние?

115
26 марта 2022, 16:00

Пишу виджет комментариев, нужно реализовать возможность сворачивание ветки с дочерними комментариями. На входе имеется json, который с помощью d3 парсится в дерево в методе updateState, далее эти данные рекурсивно отрисовываются, сначала первый родительский коммент, далее все его дети, затем второй родительский и так далее (функция renderRow). Проблема в том, что я не знаю, где хранить состояние свернутости CommentItem (непосредственно, сам блок комментария), чтобы в теле рекурсии я мог знать, свернут ли он, чтобы не добавлять его в массив, который пойдет в рендер.

import React, { useState } from 'react'
import { connect } from 'react-redux'
import { fetchComments } from '../../../redux/actions'
import * as d3 from 'd3'
import CommentItem from '../CommentItem'
const RenderRow = ({ comments }) => {
  const array = []
  const recursive = (comments, depth = 0) => {
    comments.forEach(comment => {
      array.push(
        <CommentItem
          depth={comment.parent.id === '0' ? 0 : depth}
          key={comment.id}
          comment={comment.data}
        />
      )
      if (comment.children) {
        depth += 1
        recursive(comment.children, depth)
      }
      depth -= 1
    })
  }
  if (comments.length > 0) {
    recursive(comments)
  }
  return (array)
}
class CommentList extends React.Component {
  constructor () {
    super()
    this.state = {
      comments: []
    }
  }
  updateState = () => {
    const stratify = d3.stratify()
      .id(d => d.id)
      .parentId(d => d.parentId)
    const structuredComments = stratify(this.props.comments)
    this.setState({ comments: [...structuredComments.children] })
  }
  componentDidMount () {
    this.props.fetchComments()
    this.updateState()
  }
  componentDidUpdate (prevProps) {
    const prevComments = prevProps.comments
    const currComments = this.props.comments
    const newComments = (
      prevComments.filter(i => currComments.indexOf(i) < 0)
        .concat(currComments.filter(i => prevComments.indexOf(i) < 0))
    )
    if (newComments[0]) {
      this.updateState()
    }
  }
  render () {
    return (<RenderRow comments={this.state.comments}/>)
  }
}
const mapStateToProps = ({ comments }) => ({ comments })
export default connect(
  mapStateToProps,
  { fetchComments }
)(CommentList)
READ ALSO
Как работает озвучивание текста с помощью speechSynthesis?

Как работает озвучивание текста с помощью speechSynthesis?

Возникла необходимость реализовать озвучивание текста на сайтеДля этого использовался метод speechSynthesis, но на некоторые вопросы, касающиеся...

190
Реализация мини слайдера — почему в одном случае стрелка работает правильно, а в другом нет?

Реализация мини слайдера — почему в одном случае стрелка работает правильно, а в другом нет?

Всем привет В общем, я делаю свой мини слайдер, и на этом моменте я просто застрял, не понимаю в чем ошибка

121
Максимальное значение setinterval и как его обойти

Максимальное значение setinterval и как его обойти

использую setinterval и тут у меня возник один вопросКак я понял, максимальное значение - 2147483647, если указать 2147483648, то код будет выполняться сразу

136
Multiple Select2 связанные option

Multiple Select2 связанные option

поставили мне задачу, в которой я не разбирался никогда ранее, было бы не плохо, если бы кто-нибудь смог помочь

203