【问题标题】:Toggle show/hide to a specific element切换显示/隐藏到特定元素
【发布时间】:2017-01-16 22:26:19
【问题描述】:

我有这个特殊的代码,它显示了每个问题和按钮的列表。当我单击按钮时,它将显示问题的具体答案。我的问题是,我有一堆问题,当我点击按钮时,它会显示所有答案,而不是该问题的具体答案。

这里是代码

class App extends React.Component {
 constructor(){
  super()
  this.state = {
                  answer: [],
                  isHidden: true
               }
  this.toggleHidden = this.toggleHidden.bind(this)
}

componentWillMount(){
  fetch('http://www.reddit.com/r/DrunkOrAKid/hot.json?sort=hot')
    .then(res => res.json())
    .then( (data) => {
      const answer = data.data.children.map(obj => obj.data);
      this.setState({answer});
     })
 }

toggleHidden(){
  this.setState({isHidden: !this.state.isHidden})
}

render(){
    const answer = this.state.answer.slice(2)
    return <div>
             <h1>Drunk or Kid</h1>
             {answer.map(answer =>
              <div key={answer.id}>
                <p className="title">{answer.title}</p>
                <button onClick={this.toggleHidden}>Answer</button>
                {!this.state.isHidden && <Show>{answer.selftext}</Show>}
               </div>
             )}
           </div>
  }
}
const Show = (props) => <p className="answer">{props.children}</p>

这里是codepen的链接

【问题讨论】:

  • 所有答案都共享同一个isHidden 状态。因此,当您切换该状态布尔值时,它们都会显示。您必须为每个答案隔离 isHidden 状态,以便让它们独立切换。由于 React 被设计为基于组件的,我建议为每个问题/答案组合创建一个组件,并在每个问题/答案组合中使用 isHidden 状态并映射该数据以为每个问题创建一个实例。
  • 我找到了一个很好的教程,如果您想了解更多信息:noobieprogrammer.blogspot.com/2020/09/…

标签: reactjs react-jsx


【解决方案1】:

根据我的建议,这是一个Codepen

子组件的基础是:

class Question extends React.Component {
  // Set initial state of isHidden to false
  constructor() {
    super();
    this.state = {
      isHidden: false
    }
  }
  // Toggle the visibility
  toggleHidden() {
    this.setState({
      isHidden: !this.state.isHidden
    });
  }
  // Render the component
  render() {
    const { answer } = this.props;
    return (
      <div key={answer.id}>
        <p className="title">{answer.title}</p>
        <button onClick={ () => this.toggleHidden() }>Answer</button>
        {this.state.isHidden && <Show>{answer.selftext}</Show>}
      </div>
    );
  }
}

然后您将在父组件中将其映射为:

answer.map(answer =>
    <Question answer={answer} key={answer.id} />
)

【讨论】:

  • &lt;button onClick={ () =&gt; this.toggleHidden() }&gt;Answer&lt;/button&gt; 你为什么在这里放一个回调而不是 onClick=this.toggleHidden ?在我的原始代码中,onClick=this.toggleHidden 切换有效,但是当我尝试将其粘贴到您的代码中时,它说不能设置 setState of undefined ?不过感谢您的回答。
  • @Irsyad14 您必须在构造函数中重新添加绑定。我只是在快速写一个解决方案。 this.toggleHidden = this.toggleHidden.bind(this)
  • 现在我明白了。傻我。我有点新反应。再次感谢
【解决方案2】:

另一种选择是添加一个保存打开答案 id 的状态,然后检查特定答案是否处于该状态。

让我们看看实际情况

class SomeComponent extends React.Component {
    constructor(props){
        super(props)
        this.state = {
            opened: []
        }
        this.toggleShowHide = this.toggleShowHide.bind(this)
    }
    toggleShowHide(e){
        const id = parseInt(e.currentTarget.dataset.id)
        if (this.state.opened.indexOf(id) != -1){
            // remove from array
            this.setState({opened: this.state.opened.filter(o => o !== id)})
        } else {
            this.setState({opened: [...this.state.opened, id]})
        }
    }
    render(){
        return <ul>
            { this.state.answers.map(ans => (
                <li key={ans.id} data-id={ans.id}>
                    question 
                    <button onClick={this.toggleShowHide}>show answer</button>
                    <span
                     style={{ display: this.state.opened.indexOf(ans.id) !== -1 ? 'block' : 'none' }}>answer</span>
                </li>
             ))}
       </ul>
    }
}

这是视频https://www.youtube.com/watch?v=GJsPEsckB4w

【讨论】:

    猜你喜欢
    • 2021-10-02
    • 2019-05-25
    • 2017-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-19
    • 1970-01-01
    相关资源
    最近更新 更多