维护相同的状态变量以实现 Show More/Less 功能

Maintaining same state variable to implement Show More/Less functionality

我有一个包含多张卡片的页面,其中每张卡片都有一个列表 items.I 一直在尝试在每张卡片上实施显示更多/显示更少的实施。对于一张卡片,我通过向状态对象添加两个属性来获得它。但是,如果我对所有卡片实施相同的操作,我最终会为每张卡片添加更多状态对象属性。 寻找更好的方法,我可以使用一个 common 来处理所有卡片 Show More/Less implementation

只需要一种有效的方法来实现这一点。 帮助将不胜感激

组件代码

只有两张牌的例子

import * as React from 'react';
interface IState{
  arr1:[],
  arr2: [],
  arr1ExpandFlag: boolean, // For updating Button label(More/Less)
  arr2ExpandFlag : boolean
  arr1temsToShow: number,  // Number of items to show
  arr2itemsToShow: number 
  //I will end up adding two variables one for each card
}
export default class App extends React.Component<{},IState> {

  constructor(props:any){
    super(props);
    this.state = {
      arr1 :[],
      arr2 :[],
      arr1ExpandFlag: false,
      arr1ExpandFlag: false,
      arr1itemsToShow: 3,
      arr2itemsToShow: 3,
    }
  }

  showMore = (type: string) => { // end up adding if conditions
    if(type === 'arr1')
    {
      (this.state.arr1itemsToShow === 3) ? 
      (this.setState({ arr1itemsToShow: this.state.arr1.length, arr1ExpandFlag: true })):
      (this.setState({ arr1itemsToShow: 3,arr1ExpandFlag: false}))
    }
    if(type === 'arr2')
    {
      (this.state.arr2itemsToShow === 3) ? 
      (this.setState({ arr2itemsToShow: this.state.arr2.length, arr2ExpandFlag: true })):
      (this.setState({ arr2itemsToShow: 3, arr2ExpandFlag: false}))
    }
  }

 render()    // This is just for two cards
 {
   return
   (
      <div> 
        <div>
          {this.state.arr1.slice(0, this.state.arr1itemsToShow).map((data : any, i) => 
            <p key={i}>{data.user}</p>
          )}
          <a onClick={() => this.showMore('arr1')}>
            { (this.state.arr1ExpandFlag) ? 
              ( <span>Show less</span>)   : 
              ( <span>Show more</span>)
            }
          </a>  
        </div>
       <div>
         {this.state.arr2.slice(0, this.state.arr2itemsToShow).map((data : any, i) => 
             <p key={i}>{data.user}</p>
         )}
         <a onClick={() => this.showMore('arr2')}>
          { (this.state.arr2ExpandFlag) ? 
            (<span>Show less</span>)   : 
            (<span>Show more</span>)
          }
         </a>  
      </div>
    </div>
   )
 }

正如其他人所说 - 将其构建为可重用的组件。首先确定您重复自己的地方并将其提取出来。练习会变得更容易。

我会从 Card 开始。您可以使用卡片类型(您也可以使用界面,但这是个人喜好),然后添加一个 onClickExpand 处理程序以形成此控件的 Props。

type Item = {
  user: string;
}

type Card = {
  items: Item[];
  expanded?: boolean;
  numItemsShowing: number;
}

type CardProps = Card & {
  onClickExpand: () => void;
};

const Card = (props: CardProps) => {
  const { expanded, items, numItemsShowing, onClickExpand } = props;
  return (
    <div>
      {items.slice(0, numItemsShowing).map((data, i) => (
        <p key={i}>{data.user}</p>
      ))}
      <a onClick={onClickExpand}>
        {expanded
          ? <span>Show less</span>
          : <span>Show more</span>
        }
      </a>
    </div>
  );
}

那么你的应用可以更简单:

type State = {
  card: Card[];
}

export default class App extends React.Component<{}, State> {
  state = { cards: [] };

  showMore = (index: number) => () => {
    this.setState({
      cards: this.state.cards.map((card, i) => {
        // Only modify card if it's the index we care about
        if (i === index) {
          return {
            ...card,
            expanded: true,
          }
        }
        return card;
      })
    });
  }

  addCard = () => {
    const newCard = {
      items: [],
      expanded: false,
      numItemsShowing: 0
    };

    this.setState({
      cards: [ ...this.state.cards, newCard ] // add to end of array
    });
  }

  render() {
    return (
      <div>
        {this.state.cards.map((card, i) =>
          <Card
            {...card}
            onClickExpand={this.showMore(i)}
            key={i}
          />
        )}

        <button onClick={this.addCard}>Add Card</button>
      </div>
    )
  }
}

此应用程序可让您单击按钮将新卡添加到状态。