0

like this i hava a array of components need ref to trigger the comment component collapse, so i need to create some refs to reference each commentListItem, but it doesn't work, how do i do this work?

import React, { useRef, createRef } from "react";
import PropTypes from "prop-types";
import { map, isArray } from "lodash/fp";
import Divider from "@material-ui/core/Divider";
import CommentListItem from "./CommentListItem";
import CommentCollapse from "./CommentCollapse";

function CommentList({ list = [], ...props }) {
  const { count = 0 } = props;
  const refList = map((o) => {
    /* o.ref = createRef(null); */
    return o;
  })(list);

  const onShow = () => {
    console.log(refList);
  };

  return (
    <div className="ke-comment-list">
      {map.convert({ cap: false })((o, i) => (
        <div key={i} className="ke-comment-list-item">
          <CommentListItem listItem={o} onShow={onShow} />
          {isArray(o.child) && o.child.length ? (
            <CommentCollapse {...o}>
              <CommentList list={o.child} count={count + 1} />
            </CommentCollapse>
          ) : null}
          {count > 0 && list.length - 1 === i ? null : <Divider />}
        </div>
      ))(refList)}
    </div>
  );
}

CommentList.propTypes = {
  list: PropTypes.arrayOf(PropTypes.object).isRequired,
};

export default CommentList;

there is CommentCollapse component for show or hide subcomment.

import React, { useState, forwardRef, useImperativeHandle } from "react";
import ButtonBase from "@material-ui/core/ButtonBase";
import Collapse from "@material-ui/core/Collapse";

const CommentCollapse = ({ children }, ref) => {
  const [show, setShow] = useState(false);

  const showMore = () => {
    setShow((prev) => !prev);
  };

  const collapseText = () => (show ? "收起" : "展开");

  useImperativeHandle(ref, () => ({
    showMore: showMore()
  }));

  return (
    <div className="ke-comment-list-children">
      <Collapse in={show}>{children}</Collapse>
      <ButtonBase size="small" onClick={showMore}>
        {collapseText()}
      </ButtonBase>
    </div>
  );
};

export default forwardRef(CommentCollapse);

catch errors

Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

have any idear for this situation?

  • your error has nothing got to do with ref, and likely due to you calling setState within the return clause, causing an infinite loop. Need more codes to know what you are doing. – Someone Special Nov 20 '20 at 04:22

1 Answers1

0

is fixed, just not trigger showMore function in ref.

import React, { useState, forwardRef, useImperativeHandle } from "react";
import ButtonBase from "@material-ui/core/ButtonBase";
import Collapse from "@material-ui/core/Collapse";

const CommentCollapse = ({ children }, ref) => {
  const [show, setShow] = useState(false);

  const showMore = () => {
    setShow((prev) => !prev);
  };

  const collapseText = () => (show ? "收起" : "展开");

  useImperativeHandle(ref, () => ({
    showMore
  }));

  return (
    <div className="ke-comment-list-children">
      <Collapse in={show}>{children}</Collapse>
      <ButtonBase size="small" onClick={showMore}>
        {collapseText()}
      </ButtonBase>
    </div>
  );
};

export default forwardRef(CommentCollapse);