首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在反应中有条件地渲染子组件

如何在反应中有条件地渲染子组件
EN

Stack Overflow用户
提问于 2022-07-25 18:40:40
回答 2查看 45关注 0票数 0

我有以下组件:(AddBookPanel包含AddBookForm)

我需要有能力在单击'AddBookButton‘时显示表单,也需要能够在单击'x’按钮( AddBookForm组件中的img)时隐藏表单,但是组件似乎没有正确加载,这里可能有什么问题?你认为组织这件事最好的方法是什么?

代码语言:javascript
复制
import { AddBookButton } from './AddBookButton';
import { AddBookForm } from './AddBookForm';
import { useState } from 'react';

export const AddBookPanel = () => {
  const [addBookPressed, setAddBookPressed] = useState(false);

  return (
    <div>
      <div onClick={() => setAddBookPressed(!addBookPressed)}>
        <AddBookButton />
      </div>
      <AddBookForm initialFormActive={addBookPressed} />
    </div>
  );
};
代码语言:javascript
复制
import { useState } from 'react';

interface AddBookFormProps {
  initialFormActive: boolean;
}

export const AddBookForm: React.FC<AddBookFormProps> = ({
  initialFormActive,
}) => {
  const [isFormActive, setIsFormActive] = useState(initialFormActive);

  return (
    <>
      {isFormActive && (
        <div className="fixed box-border h-2/3 w-1/3 border-4 left-1/3 top-24 bg-white border-slate-600 shadow-xl">
          <div className="flex justify-between bg-slate-400">
            <div>
              <p className="text-4xl my-5 mx-6">Add a new Book</p>
            </div>
            <div className="h-16 w-16 my-3 mx-3">
              <button onClick={() => setIsFormActive(!isFormActive)}>
                <img
                  src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/OOjs_UI_icon_close.svg/1200px-OOjs_UI_icon_close.svg.png"
                  alt="close-button"
                  className="object-fit"
                ></img>
              </button>
            </div>
          </div>

          <div className="flex-col">
            <div className="flex justify-between my-10 ml-5 text-xl">
              <input type="text" placeholder="book name"></input>
            </div>
          </div>
        </div>
      )}
    </>
  );
};
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-25 18:46:18

您总是呈现AddBookForm。这意味着在初始呈现中,useState是用false调用的。因为您从未调用过setIsFormActive,所以它现在被卡住为“不呈现”。

只是不要使用useState,直接使用属性initialFormActive。并可能将其重命名为isFormActive。让父级处理状态更改。

代码语言:javascript
复制
import { AddBookButton } from './AddBookButton';
import { AddBookForm } from './AddBookForm';
import { useState } from 'react';

export const AddBookPanel = () => {
  const [addBookPressed, setAddBookPressed] = useState(false);

  return (
    <div>
      <div onClick={() => setAddBookPressed(!addBookPressed)}>
        <AddBookButton />
      </div>
      <AddBookForm initialFormActive={addBookPressed} onClose={() => setAddBookPressed(false)} />
    </div>
  );
};
代码语言:javascript
复制
import { useState } from 'react';

interface AddBookFormProps {
  initialFormActive: boolean;
  onColse: () => void;
}

export const AddBookForm: React.FC<AddBookFormProps> = ({
  initialFormActive,
  onClose,
}) => {
  // const [isFormActive, setIsFormActive] = useState(initialFormActive); don't use this frozen state, allow the parent to control visibility

  return (
    <>
      {initialFormActive && (
        <div className="fixed box-border h-2/3 w-1/3 border-4 left-1/3 top-24 bg-white border-slate-600 shadow-xl">
          <div className="flex justify-between bg-slate-400">
            <div>
              <p className="text-4xl my-5 mx-6">Add a new Book</p>
            </div>
            <div className="h-16 w-16 my-3 mx-3">
              <button onClick={() => onClose()}>
                <img
                  src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/OOjs_UI_icon_close.svg/1200px-OOjs_UI_icon_close.svg.png"
                  alt="close-button"
                  className="object-fit"
                ></img>
              </button>
            </div>
          </div>

          <div className="flex-col">
            <div className="flex justify-between my-10 ml-5 text-xl">
              <input type="text" placeholder="book name"></input>
            </div>
          </div>
        </div>
      )}
    </>
  );
};
票数 1
EN

Stack Overflow用户

发布于 2022-07-25 18:53:32

代码的问题在于如何将initialFormActive绑定到AddBookForm组件的内部状态。当查看useState在AddBookForm中时,很明显,AddBookForm initialFormActive只影响您的初始状态,当查看您的父组件时,我可以清楚地看到您将false作为initialFormActive支柱的值传递,从而使用false值初始化AddBookForm中的状态(表单将保持隐藏)。然后,当您单击按钮,当支柱值发生变化(变为真)时,您的<AddBookForm />将变得可见,但这并不是因为您只使用了初始值(False)和道具值更改之后,就完全解耦了。

由于您希望控制组件之外的可见性,所以应该将两个支持附加到AddBookForm、isVisibletoggleVisibiliy。做这样的事:

代码语言:javascript
复制
 export const AddBookPanel = () => {
  const [addBookPressed, setAddBookPressed] = useState(false);
  const toggleAddBookPressed = () => setAddBookPressed(p => !p);

  return (
    <div>
      <div onClick={() => setAddBookPressed(!addBookPressed)}>
        <AddBookButton />
      </div>
      <AddBookForm isVisible={addBookPressed} toggleVisibility={toggleAddBookPressed } />
    </div>
  );

};

代码语言:javascript
复制
export const AddBookForm: React.FC<AddBookFormProps> = ({
  isVisible, toggleVisibility
}) => {

  return (
    <>
      {isVisible&& (
        <div className="fixed box-border h-2/3 w-1/3 border-4 left-1/3 top-24 bg-white border-slate-600 shadow-xl">
          <div className="flex justify-between bg-slate-400">
            <div>
              <p className="text-4xl my-5 mx-6">Add a new Book</p>
            </div>
            <div className="h-16 w-16 my-3 mx-3">
              <button onClick={toggleVisibility}>
                <img
                  src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/OOjs_UI_icon_close.svg/1200px-OOjs_UI_icon_close.svg.png"
                  alt="close-button"
                  className="object-fit"
                ></img>
              </button>
            </div>
          </div>

          <div className="flex-col">
            <div className="flex justify-between my-10 ml-5 text-xl">
              <input type="text" placeholder="book name"></input>
            </div>
          </div>
        </div>
      )}
    </>
  );
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73113917

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档