css 如何在React中只打开已单击的行数据?

wi3ka0sx  于 2023-01-10  发布在  React
关注(0)|答案(2)|浏览(105)

我定义了一个名为fullText的状态变量。
默认值为false
当单击“全文”时,我想反转状态值,使文本可以关闭和打开。但当单击它时,表中所有行的文本都打开了,我如何使它特定于行呢?

{
  !this.state.fullText ?

       <div onClick={() => this.setState({ fullText: !this.state.fullText })} 
       className="text-primary cursor-pointer font-size-14 mt-2 px-2"  
        key={props.data?.id}>
                Full Text 
        </div>
         :
         <>
       <div onClick={() => this.setState({ fullText: !this.state.fullText 
          })}className="text-primary cursor-pointer font-size-14 mt-2 px-2" 
          key={props.data?.id}>
                 Short Text 
       </div>
               <span>{ props.data?.caption}</span>
        </>
          }
wljmcqd8

wljmcqd81#

看起来问题中的代码样本对每一行都是重复的,但是只有一个状态fullText(CodeSandbox中的showMore)对所有这些行是公共的,因此它们都是一起打开或关闭的。
如果您希望每一行都有单独的打开/关闭功能,那么您需要每行有一个这样的状态。一个简单的解决方案是将此状态嵌入到每行的数据中:

export default class App extends Component {
  state = {
    data: [
      {
        id: 1,
        description: "aaaaa",
        showMore: false // Initially closed
      },
      // etc.
    ]
  };

  render() {
    return (
      <>
        {this.state.data.map((e) => (
          <>
            { /* Read the showMore state of the row, instead of a shared state */
              e.showMore === false ? (
              <div onClick={() => this.setState({ data: changeShow(this.state.data, e.id, true) })}>
                Show description{" "}
              </div>
            ) : (
              <>
                <div onClick={() => this.setState({ data: changeShow(this.state.data, e.id, false) })}>
                  Show less{" "}
                </div>
                <span key={e.id}>{e.description} </span>
              </>
            )}
          </>
        ))}
      </>
    );
  }
}

/**
 * Update the showMore property of the
 * row with the given id.
 */
function changeShow(data, id, show) {
  for (const row of data) {
    if (row.id === id) { // Find the matching row id
      row.showMore = show; // Update the property
    }
  }
  return data;
}
zysjyyx4

zysjyyx42#

有两个特定的想要的输出你可能想要.你可以任一个使它在一个时间只打开一行.你也可以使它们单独的行特定到打开或关闭独立.
为了使特定行独立运行,您可以为展开视图的状态存储一个id列表,并显示相关组件或行为。

class RowSpecific extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedIds: [],
      data: [
        { id: "1", otherInfo: {} },
        { id: "2", otherInfo: {} },
        { id: "3", otherInfo: {} },
      ],
    };
    this.handleExpandHide = this.handleExpandHide.bind(this);
  }
  handleExpandHide(expand, id) {
    if (!id) return;
    let sIds = [...this.state.selectedIds];
    if (expand) sIds.push(id);
    else sIds.remove((rId) => rId === id);
    this.setState({
      selectedIds: sIds,
    });
  }
  render() {
    let list = this.state.data.map((data) => {
      let show = this.state.selectedIds.find((id) => data.id === id);
      return show ? (
        <ExpandedView
          data={data}
          onExpandHide={(e) => {
            this.handleExpandHide(true, data.id);
          }}
        />
      ) : (
        <CollapseView
          data={data}
          onExpandHide={(e) => {
            this.handleExpandHide(true, data.id);
          }}
        />
      );
    });
    return list;
  }
}

为了使它一次只打开一个,你可以保存点击的id的状态,然后当显示它时,只有匹配的id的状态应该显示为打开。其余的是关闭的。

class SingleRow extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedId: "2",
      data: [
        { id: "1", otherInfo: {} },
        { id: "2", otherInfo: {} },
        { id: "3", otherInfo: {} },
      ],
    };
  }
  render() {
    let list = this.state.data.map((data) => {
      let show = data.id === this.state.selectedId;
      return show ? <ExpandedView data={data} /> : <CollapseView data={data} />;
    });
    return list;
  }
}

相关问题