【问题标题】:react component not working properly when rendered multiple times多次渲染时反应组件无法正常工作
【发布时间】:2021-09-19 08:45:38
【问题描述】:

下面给出的是反应组件(Newsitem)的代码,我已经通过 API 将标题作为道具传递。在 Newsitem 中有一个 span 标签,当在 Newsitem 中传递的标题包含少于 70 个字符时,我需要将其隐藏。但这不会发生,发生的情况是,每当标题少于 70 个字符时,所以呈现的第一个 newsItem 的 span 标签会被隐藏,而不是该标题所属的那个 newsitem 的标签

export class NewsItem extends Component { 
  state = {
    title: true
  }
  componentDidMount(){

    let readTitle = document.getElementById('readTitle')
    if(this.props.title.length<70){
      readTitle.style.visibility = 'hidden'
      console.log('Done....');
    }
    console.log('componentDidMount() lifecycle');

    this.setState({title : !this.state.title})
  }
  
  render() {
    console.log('Render lifecycle');
      let {title , description , imageURL , newsURL} = this.props; 
      
    return (
      <>
        <div>
          <div className="card" style={{width: '18rem'}}>
            <img src={imageURL} className="card-img-top" alt="..."/>
            <div className="card-body">
              <h5 className="card-title" style={{display: 'inline'}} id='title'>{title}</h5>
              <span id='readTitle'><b>Read More</b></span>
              <p className="card-text">{description}</p>
              <a href={newsURL} target='_blank' rel="noreferrer" className="btn btn-sm btn-dark">Read More</a>
            </div>
          </div>      
        </div>
      </>
      
    );    
  }
}
export default NewsItem;

【问题讨论】:

  • 问题是你使用document.getElementById,然后将多个相同的元素渲染到DOM。显然,getElementById 只接收到第一个。您应该改用 ref,它可以在组件的范围内被引用。

标签: reactjs react-component


【解决方案1】:

除了我的评论之外,我可能会使用无状态功能组件和 React.useRef 挂钩并执行以下操作:

import React, {useRef, useEffect} from 'react';

const NewsItem = ({title , description , imageURL , newsURL}) => {

  const readTitle = useRef(null);

  useEffect(()=>{
    if(title.length<70){
      readTitle.current.style.visibility = 'hidden'
      console.log('Done....');
    }
  }, [title])

  return (
      <div>
        <div className="card" style={{width: '18rem'}}>
          <img src={imageURL} className="card-img-top" alt="..."/>
          <div className="card-body">
            <h5 className="card-title" style={{display: 'inline'}} id='title'>{title}</h5>
            <span ref={readTitle}><b>Read More</b></span>
            <p className="card-text">{description}</p>
            <a href={newsURL} target='_blank' rel="noreferrer" className="btn btn-sm btn-dark">Read More</a>
          </div>
        </div>
      </div>
  );
};

export default NewsItem;

应该可以按预期工作,并且更加简洁:)

【讨论】:

    【解决方案2】:

    react 中有一个非常重要的规则,就是不要在组件中间使用 js dom 函数。如果您使用它们,您可能会在组件和状态之间产生冲突。在这种情况下,您可以改为使用 React refs。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-28
      • 2022-01-08
      • 2015-08-26
      • 1970-01-01
      • 1970-01-01
      • 2021-05-04
      • 2018-07-30
      • 1970-01-01
      相关资源
      最近更新 更多