如何在React JS中更改旧状态

时间:2019-12-29 15:03:21

标签: javascript reactjs

我有Faq个组件的列表。当我单击一个问题时,需要显示该特定问题的答案,而所有其他答案都需要隐藏。
我的问题是,我有很多问题,当我单击一个问题时,它显示的是所单击问题的答案,但并没有隐藏其他已经打开的答案。

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

function Faq(props) {
   const [toggle, setToggle] = useState(false);
   return (
      <div>
        <h2 onClick={() => setToggle(true)}>
        <strong>{props.question}</strong></h2>
        {toggle && <p>{props.answer}</p>}   
     </div>
   )

 }

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

3 个答案:

答案 0 :(得分:1)

以下是您的许多解决方案之一:

import React, { useState } from 'react';

function Faq(props) {
   return (
      <div>
        <h2 onClick={() => { props.clickHandler(props.qid) }}>
        <strong>{props.question}</strong></h2>
        { props.toggle === props.qid && <p>{props.answer}</p> }   
     </div>
   )
 }

 function Faqs() { 
   const [toggle, setToggle] = React.useState("0");

   handleClick = qid => {
     setToggle(qid);
   }

      return (
           <div>
             <Faq qid="1" question={"Question 1"} answer={"answer 1"} clickHandler={handleClick} toggle={toggle} />
             <Faq qid="2" question={"Question 2"} answer={"answer 2"} clickHandler={handleClick} toggle={toggle} />
           </div>
      )
 }

分配初始值toggle而不是切换true false"0"。为每个问题分配一个qid,并将其与props一起传递。当前可见答案的问题qid将设置为状态,答案的可见性取决于与单击的问题qid匹配的状态的当前值。

如果再次单击该问题,您还可以选择隐藏该问题的已显示答案,方法是检查所单击的问题的qid是否与当前状态相同,然后再将toggle设置为到"0"(初始状态)。

可以随意将变量名toggle更改为currentQuestion之类的名称,因为现在我们存储的是问题qid而不是truefalse

我知道可以进一步优化它,但是它将作为一个良好的“工作”起点。显然,您不需要重复在<Faq />中传递所有这些道具,因为我认为最终您将为此使用数组.map()

希望您能理解这一点,否则我将对此进行详细说明。

答案 1 :(得分:0)

首先,您的 setToggle 函数仅将切换值设置为 true 。 其次,通过单击特定的 FAQ 组件,不会在其余部分中触发 onClick 事件 FAQ 组件。

最佳解决方案是在父组件中保留一个状态变量以存储当前打开的问题,然后为所有 FAQ 组件共同调用一个函数。< / p>

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

function Faq(props) {
   return (
      <div>
        <h2 onClick={() => props.onClick(prop.toggle === props.question ? '' : prop.question)}>
        <strong>{props.question}</strong></h2>
        {(props.toggle === props.question) && <p>{props.answer}</p>}   
     </div>
   )

 }

 function Faqs(props) {
      const [toggle, setToggle] = useState('');
      return (
           <div>
             <Faq
               question={"Question 1"}
               answer={"answer 1"}
               onClick={setToggle}
               toggle={toggle}
             />
             <Faq
               question={"Question 2"}
               answer={"answer 2"}
               onClick={setToggle}
               toggle={toggle}
             />

           </div >
      )
 }

答案 2 :(得分:0)

这是您可以优化方式使用多个列表的方式。如果您有很多列表,只需遍历map而不是编写硬编码。

let data = [{qid:1,question: "Question 1", answer:"Answer 1"},
{qid:2,question: "Question 2", answer:"Answer 2"},
{qid:3,question: "Question 3", answer:"Answer 3"},
{qid:4,question: "Question 4", answer:"Answer 4"},
{qid:5,question: "Question 5", answer:"Answer 5"}]
function Faq(props) {
   return (
      <div>
        <h2 style={{background:'lightgrey'}} onClick={() => { props.clickHandler(props.qid) }}>
        <strong>{props.question}</strong></h2>
        { props.toggle === props.qid && <p>{props.answer}</p> }   
     </div>
   )
 }

 function Faqs() { 
   const [toggle, setToggle] = React.useState("0");

   const handleClick = qid => {
     console.log(qid)
     setToggle(qid);
   }

      return (
           <div>
             {data.map(({answer,question,qid})=>
              <Faq qid={qid} question={question} 
               clickHandler={handleClick} 
               toggle={toggle} 
               answer={answer} />
              )}
           </div>
      )
 }

Live demo