【问题标题】:Show or Hide a particular element in react在反应中显示或隐藏特定元素
【发布时间】:2018-09-21 05:33:33
【问题描述】:

我必须显示常见问题解答列表,并且我需要隐藏问题的答案。当我单击问题时,需要显示该特定问题的答案。我的问题是,我有一堆问题,当我点击按钮时,它会显示所有答案,而不是该问题的具体答案。

class Faqs extends Component {
  constructor(props){
    super(props);
    this.state = {
      isHidden: true
    }
  }
  toggleHidden () {
    this.setState({
      isHidden: !this.state.isHidden
    })
  }
render() {
        return (
            <div>
               <span onClick={() => this.toggleHidden()}><strong>This is the question</strong></span>
               {!this.state.isHidden && <p>Answer for the question</p>} <br/>

               <span onClick={() => this.toggleHidden()}><strong>Question2</strong></span>
               {!this.state.isHidden && <p>Answer2</p>} <br/>
               <hr></hr>            
            </div >
        )
    }
}

【问题讨论】:

标签: reactjs toggle


【解决方案1】:

您可以将您的组件再分解为一个级别,以拥有一个仅呈现问题和相应答案的子组件。将问题和答案作为道具传递。这样,您可以对所有问题使用相同的组件,但每个问题/答案对都有自己的状态。

class Faq extends Component{
 state = {isHidden: true}
 toggleHidden = ()=>this.setState((prevState)=>({isHidden: !prevState.isHidden}))
 render(){
  return(
     <div>
     <span onClick={this.toggleHidden}>
           <strong>{props.question}</strong></span>
           {!this.state.isHidden && <p>{props.answer}</p>}   
     </div>
  )
 }
}




class Faqs extends Component {

render() {
        return (
            <div>
              <Faq question={"Question 1"} answer={"answer 1"} />
              <Faq question={"Question 2"} answer={"answer 2"} />
            </div >
        )
    }
}

【讨论】:

    【解决方案2】:

    理想情况下,您应该在某种列表中列出常见问题解答 - 然后当您遍历它们时,每个都会分配一个索引号 - 然后当您切换单个答案时,您将该索引存储在状态中并通过 DOM 操作那个号码。

    编辑。在当今时代,只适合展示使用钩子的示例:

    const {useState} = React;
    
    const FaqApp = () => {
      const [ selectedQuestion, toggleQuestion ] = useState(-1);
      
      function openQuestion(index) {
        toggleQuestion(selectedQuestion === index ? -1 : index);
      }
    
      const faqs = getFaqs();
    
      return (
        <div>
          <h2>FAQs:</h2>
            {faqs.map(( { question, answer}, index) => (
              <div key={`item-${index}`} className={`item ${selectedQuestion === index ? 'open' : ''}`}>
                <p className='question' onClick={() => openQuestion(index)}>{question}</p>
                <p className='answer'>{answer}</p>
              </div>
            ))}
        </div>
      )
    }
    
    function getFaqs() {
      const faqs = [
        {
          question: 'Question 1',
          answer: 'answer 1'
        },
        {
          question: 'Question 2',
          answer: 'answer 2'
        }
      ];
      return faqs;
    }
    
    
    ReactDOM.render(
      <FaqApp />,
      document.getElementById("react")
    );
    body {
      background: #fff;
      padding: 20px;
      font-family: Helvetica;
    }
    
    #app {
      background: #fff;
      border-radius: 4px;
      padding: 20px;
      transition: all 0.2s;
    }
    
    h2 {
       margin-bottom: 11px;
    }
    
    .item + .item {
      margin-top: 11px;
    }
    
    .question {
      font-weight: bold;
      cursor: pointer;
    }
    
    .answer {
       display: none;
    }
    
    .open .answer {
      display: block;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
    <div id="react"></div>

    这篇文章的旧版本:

    我写了一个简单的例子,让你有多个问题:

    class FaqApp extends React.Component {
      constructor(props) {
        super(props)
        this.state = {
          // start the page with all questions closed
        	selectedQuestion: -1
        };
        this.openQuestion = this.openQuestion.bind(this);
      }
    	
      getFaqs() {
      	// some service returning a list of FAQs
      	const faqs = [
          {
            question: 'Question 1',
            answer: 'answer 1'
          },
          {
            question: 'Question 2',
            answer: 'answer 2'
          }
        ];
        return faqs;
      }
      
      openQuestion(index) {
        // when a question is opened, compare what was clicked and if we got a match, change state to show the desired question.
      	this.setState({
        	selectedQuestion: (this.state.selectedQuestion === index ? -1 : index)
        });
      }
      
      render() {
        // get a list of FAQs
        const faqs = this.getFaqs();
        return (
          <div>
            <h2>FAQs:</h2>
              {faqs.length && faqs.map((item, index) => (
                <div key={`item-${index}`} className={`item ${this.state.selectedQuestion === index ? 'open' : ''}`}>
                    <p className='question' onClick={() => this.openQuestion(index)}>
                      {item.question}
                    </p>
                    <p className='answer'>
                      {item.answer}
                    </p>
                </div>
              ))}
          </div>
        )
      }
    }
    
    ReactDOM.render(<FaqApp />, document.querySelector("#app"))
    body {
      background: #20262E;
      padding: 20px;
      font-family: Helvetica;
    }
    
    #app {
      background: #fff;
      border-radius: 4px;
      padding: 20px;
      transition: all 0.2s;
    }
    
    h2 {
       margin-bottom: 11px;
    }
    
    .item + .item {
      margin-top: 11px;
    }
    
    .question {
      font-weight: bold;
      cursor: pointer;
    }
    
    .answer {
       display: none;
    }
    
    .open .answer {
      display: block;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    
    <div id="app"></div>

    【讨论】:

    • IMO 这是一种更合适的 ReactJS 解决方案。
    【解决方案3】:

    问题是您正在使用 一个 布尔状态片段来控制多个片段的逻辑。这是使用单独组件的经典场景。

    创建一个新组件ToggleQuestion,它封装了显示/显示机制。

    Faqs 组件改为管理ToggleQuestion 组件列表。

    const QUESTIONS = [
      { title: 'q1', answer: 'a1' },
      { title: 'q2', answer: 'a2' }
    ]
    
    class ToggleQuestion extends React.Component {
      constructor (props) {
        super(props)
        this.state = { isHidden: true }
      }
      
      toggleHidden () {
        this.setState({ isHidden: !this.state.isHidden })
      }
      
      render () {
        const { question, answer } = this.props
        const { isHidden } = this.state
        return (
          <div>
            <span>{question}</span>
            { !isHidden && <span>{answer}</span> }
            <button onClick={this.toggleHidden.bind(this)}>
              Reveal Answer
            </button>
          </div>
        )
      }
    }
    
    class Faqs extends React.Component {
      render () {
        return (
          <div>
            { QUESTIONS.map(question => (
              <ToggleQuestion
                question={question.title}
                answer={question.answer}
              />
            ))}
          </div>
        )
      }
    }
    
    ReactDOM.render(<Faqs />, document.getElementById('container'))
    <div id='container'></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

    【讨论】:

      【解决方案4】:

      我会为答案编写一个不同的处理程序。将来,如果您需要更多逻辑来回答将是可扩展的。注意renderAnswer

      class Faqs extends Component {
        constructor(props){
          super(props);
          this.state = {
            isHidden: true
          }
        }
        toggleHidden () {
          this.setState({
            isHidden: !this.state.isHidden
          })
        }
        renderAnswer() {
          if (this.state.isHidden) {
            return;
          }
          return (
            <p>Answer</p>
          );
        }
        render() {
          return (
                  <div>
                     <span onClick={() => this.toggleHidden()}><strong>This is the question</strong></span>
                     { this.renderAnswer() } <br/>
      
                     <span onClick={() => this.toggleHidden()}><strong>Question2</strong></span>
                     { this.renderAnswer() } <br/>
                     <hr></hr>            
                  </div >
              )
          }
      }
      

      【讨论】:

        【解决方案5】:

        这是做你想做的另一种方式。 (这一次只能打开一个)

        class Faqs extends Component {
          constructor(props){
            super(props);
            this.state = {
              hiddenId: null,
            }
          }
          setHiddenId(id) {
            this.setState({
              hiddenId: id
            })
          }
          render() {
                return (
                    <div>
                       <span onClick={() => this.setHiddenId('one')}><strong>This is the question</strong></span>
                       {this.state.hiddenId === 'one' && <p>Answer for the question</p>} <br/>
        
                   <span onClick={() => this.setHiddenId('two')}><strong>Question2</strong></span>
                   {this.state.hiddenId === 'two' && <p>Answer2</p>} <br/>
                   <hr></hr>            
                </div >
            )
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2021-05-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-21
          • 2021-09-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多