简体   繁体   English

如何在 React js 中更改旧状态

[英]How to change old state in React js

I have a list of Faq components.我有一个Faq组件列表。 When I click on a question, the answer for that particular question needs to be shown, and all other answers need to be hidden.当我点击一个问题时,需要显示该特定问题的答案,并且需要隐藏所有其他答案。
My problem is, I have a bunch of questions, and when I click on a question, it's showing the answer for the clicked question, but it's not hiding other answers which which were already opened.我的问题是,我有一堆问题,当我点击一个问题时,它会显示所点击问题的答案,但它并没有隐藏已经打开的其他答案。

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 >
      )
 }

First of all, your setToggle function only sets toggle value to be true .首先,您的setToggle函数仅将切换值设置为true Secondly, by clicking on a particular FAQ component will not trigger the onClick event in rest of the FAQ components.其次,通过单击特定的FAQ组件不会触发其余FAQ组件中的onClick事件。

Best solution is keeping a state variable to store which question is open at the moment in parent component and then a function to be invoked commonly for all FAQ component.最好的解决方案是保持一个状态变量来存储当前在父组件中哪个问题是开放的,然后一个函数被所有FAQ组件共同调用。

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 >
      )
 }

Here's one of the many solutions to your problem:以下是您问题的众多解决方案之一:

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>
      )
 }

Instead of switching toggle true and false , assign an initial value of "0" .不是切换toggle truefalse ,而是分配初始值"0" Assign each question a qid and pass it along with the props .为每个问题分配一个qid并将其与props一起传递。 The currently visible answer's question qid will be set in the state and answer's visibility will depend upon the current value of state matching the clicked question's qid .当前可见答案的问题qid将在状态中设置,答案的可见性将取决于与单击问题的qid匹配的状态的当前值。

You can also choose to hide the question's already displayed answer if it is re-clicked by checking if the clicked question's qid is the same as what is currently in the state and setting the toggle back to "0" (the initial state).您还可以通过检查单击的问题的qid是否与当前状态相同并将toggle设置回"0" (初始状态)来选择在重新单击时隐藏问题已显示的答案。

Feel free to change the variable name toggle to something like currentQuestion or anything that makes sense, because now we're storing the question qid , instead of true or false .随意将变量名称toggle更改为currentQuestion或任何有意义的东西,因为现在我们正在存储问题qid ,而不是truefalse

I know this can be optimised further but will serve as a good "working" starting point.我知道这可以进一步优化,但将作为一个很好的“工作”起点。 Obviously, you won't need to repeat passing all those props in <Faq /> because I think ultimately you'll use Array .map() for this.显然,您不需要在<Faq />重复传递所有这些道具,因为我认为最终您将为此使用 Array .map()

Hope you understand this, else I will elaborate more on this.希望你明白这一点,否则我会详细说明这一点。

This is how you can work with multiple lists in optimized way.这就是您可以以优化的方式处理多个列表的方式。 if you have many list just iterate through map instead of writing hard coding.如果您有很多列表,只需遍历 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现场演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM