0

我正在根据我拥有的 JSON 文件创建一个常见问题解答部分,该文件包含一组带有“问题”和“答案”的对象。在此处输入图像描述 它设置为当您单击左侧的问题时,它会在右侧显示相应的答案...确实可以正常工作。问题是当用户再次单击该问题并且该部分不起作用时,我想隐藏数据。当我再次单击一个问题时,它会更改图标,但不会更改右侧的框。当再次单击问题时,我希望答案框完全消失。

我猜这是我在设置状态时做错的事情:

const [clickedIndex, setClickedIndex] = useState({});
  const [displayAnswer, setDisplayAnswer] = useState();

  const handleClick = (index) => () => {
    setClickedIndex((state) => ({
      [index]: !state[index],
    }));
    setDisplayAnswer(faqdata[index].Answer);
    console.log(displayAnswer);
  };

<Grid container spacing={3}>
            <Grid item>
              <List
                style={{
                  maxHeight: 430,
                  width: 500,
                  overflow: 'auto',
                  border: '1px solid black',
                }}
              >
                {faqdata.map((item, index) => (
                  <ListItem style={{ cursor: 'pointer' }}>
                    <ListItemIcon>
                      {clickedIndex[index] ? <RemoveIcon /> : <AddIcon />}
                    </ListItemIcon>
                    <ListItemText
                      primary={item.Question}
                      onClick={handleClick(index)}
                    />
                  </ListItem>
                ))}
              </List>
            </Grid>
            <Grid item>
              <List
                style={{
                  maxHeight: 430,
                  width: 500,
                  overflow: 'auto',
                  border: '1px solid black',
                }}
              >
                <ListItem>{displayAnswer}</ListItem>
              </List>
            </Grid>
          </Grid>

4

1 回答 1

0

我会考虑使用单个状态变量来存储当前打开的答案,它可以是:

  • null(意味着没有答案是开放的)
  • 一个数字(表示该索引问题的答案是开放的)
const Container = () => {
  const [openQuestion, setOpenQuestion] = useState(null);

  const toggleOpenQuestion = (index) => {
    if(openQuestion === index) {
      setOpenQuestion(null)
    } 

    setOpenQuestion(index)
  }

  return <UIComponents openQuestion={openQuestion} toggleOpenQuestion={toggleOpenQuestion}/>
}

然后在 UI 中,您可以根据该值确定要显示的内容,如下所示:

<Grid container spacing={3}>
  <Grid item>
    <List
      style={{
        maxHeight: 430,
        width: 500,
        overflow: "auto",
        border: "1px solid black",
      }}
    >
      {faqdata.map((item, index) => (
        <ListItem style={{ cursor: "pointer" }}>
          <ListItemIcon>
            {openQuestion === index ? <RemoveIcon /> : <AddIcon />}
          </ListItemIcon>
          <ListItemText primary={item.Question} onClick={() => toggleOpenQuestion(index)} />
        </ListItem>
      ))}
    </List>
  </Grid>
  <Grid item>
    <List
      style={{
        maxHeight: 430,
        width: 500,
        overflow: "auto",
        border: "1px solid black",
      }}
    >
      <ListItem>{displayAnswer}</ListItem>
    </List>
  </Grid>
</Grid>;

在这里值得一提的是,您可能应该将 toggleOpenQuestion 函数包装在 useCallback 中,以防止子组件中不必要的重新渲染:

const toggleOpenQuestion = useCallback((index) => {
    if(openQuestion === index) {
      setOpenQuestion(null)
    } 

    setOpenQuestion(index)
}, [openQuestion])
于 2021-03-02T13:50:52.160 回答