如果CSS省略号在React组件中处于活动状态,我如何有条件地显示标题工具提示

时间:2018-08-15 20:25:00

标签: javascript reactjs

问题

我正在寻找一种干净的方法来在应用了CSS省略号的项目上显示标题工具提示。 (在React组件内)

我尝试过的事情:

我设置了一个引用,但是直到componentDidUpdate才存在,因此在componentDidUpdate中我强制执行Update。 (这需要更多的返工来处理道具更改,而我可能会改用setState。)这种工作,但是有很多警告是我无法接受的。

  1. setState / forceUpdate-也许这是必要的罪恶
  2. 如果浏览器大小改变怎么办?每次调整大小都需要重新渲染吗?我想我也需要对此进行反跳。好吧。

问题:

是否有更优雅的方法来实现此目标?

半功能MCVE:

https://codepen.io/anon/pen/mjYzMM

class App extends React.Component {
  render() {
    return (
      <div>
        <Test message="Overflow Ellipsis" />
        <Test message="Fits" />
      </div>
    );
  }
}

class Test extends React.Component {
  constructor(props) {
    super(props);
    this.element = React.createRef();
  }
  componentDidMount() {
    this.forceUpdate();
  }

  doesTextFit = () => {
    if (!this.element) return false;
    if (!this.element.current) return false;
    console.log(
      "***",
      "offsetWidth: ",
      this.element.current.offsetWidth,
      "scrollWidth:",
      this.element.current.scrollWidth,
      "doesTextFit?",
      this.element.current.scrollWidth <= this.element.current.offsetWidth
    );

    return this.element.current.scrollWidth <= this.element.current.offsetWidth;
  };
  render() {
    return (
      <p
        className="collapse"
        ref={this.element}
        title={this.doesTextFit() ? "it fits!" : "overflow"}
      >
        {this.props.message}
      </p>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("container"));
.collapse {
    width:60px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<div id="container"></div>

1 个答案:

答案 0 :(得分:0)

由于许多人仍在查看此问题。我终于弄清楚了怎么做。有时我会尝试将其重写为一个有效的示例,但这是要点。

// Setup a ref
const labelRef = useRef(null);

// State for tracking if ellipsis is active
const [isEllipsisActive, setIsEllipsisActive] = useState(false);

// Setup a use effect
useEffect(() => {
    if(labelRef?.current?.offsetWidth < labelRef?.current?.scrollWidth) {
        setIsEllipsisActive(true);
    }
}, [labelRef?.current, value, isLoading]); // I was also tracking if the data was loading

// Div you want to check if ellipsis is active
<div ref={labelRef}>{value}</div>