reactjs 将prop逻辑重构为不同的组件

tf7tbtn2  于 2023-03-17  发布在  React
关注(0)|答案(1)|浏览(97)

我有一个BaseUI组件,其属性为

<BaseUI
  onLogout={()=> // logout logic}
  applicationName= "XXXX"
  appBarItems = {[
    <a href={actualUrl} onClick={HomeClick} className="Home" />,
      <div className="AdvanceSearch">
        {searchTextVisible ? (
          <TextField
            fullWidth className="AdvanceSearchTextWidth"
            label=""
            value={searchText}
            onKeyPress={(ev: any) => {
              if (ev.key === "Enter") {                    
                window.location.href = window.location.href.toString().substr(0,window.location.href.indexOf("#") + 1) + "/advancesearch/" + searchText.toString() .split("/").join("_");
                ev.preventDefault();
              }
            }}
            onChange={(v: string) => {
            setSearchText(v);}}
            placeholder="Search here"
          />
        ) : ("")}
      {searchTextVisible ? <Icon name="cross" onClick={HideSearch} /> : ""}
      {!searchTextVisible ? <Icon name="search" onClick={ShowSearch} /> : ""}
    </div>,
    // and some more <div></div> goes here
  ]}
/>

目前我想将appBarItems中的代码重构到另一个文件/组件中。我尝试将代码添加到另一个组件中

const appBarItems = (): ReactElement<IAppBarItem[]> => {
  return (
    <div>
      <a href={actualUrl} onClick={HomeClick} className="Home" />,
      <div className="AdvanceSearch">
        {searchTextVisible ? (
          <TextField
            fullWidth className="AdvanceSearchTextWidth"
            label=""
            value={searchText}
            onKeyPress={(ev: any) => {
              if (ev.key === "Enter") {
                window.location.href = window.location.href.toString().substr(0, window.location.href.indexOf("#") + 1) +                       "/advancesearch/" + searchText.toString() .split("/").join("_");
                ev.preventDefault();
              }
            }}
          onChange={(v: string) => {
          setSearchText(v);}}
          placeholder="Search here"
        />) : ("")}
        {searchTextVisible ? <Icon name="cross" onClick={HideSearch} /> : ""}
        {!searchTextVisible ? <Icon name="search" onClick={ShowSearch} /> : ""}
      </div>
    </div>
  )
}

状态变量是使用UseState声明的,它几乎没有箭头函数。
并尝试将其用于BaseUI

<BaseUI
...
appBarItems = AppBarItems// gives error
appBarItems = [AppBarItems]// gives error
</BaseUI>

错误是

Type '() => ReactElement<IAppBarItem[]>' is 
not assignable to type 'ReactElement<(({ iconName, text, tooltip, 
onClick, className, style, dataAttributes 
}: IAppBarItem) => Element) 
| (({ iconName, href, openInNewTab, 
tooltip, className, style, dataAttributes 
}: IAppBarAnchor) => Element), 
string | JSXElementConstructor<any>> 
[]'.ts(2322)
20jt8wwn

20jt8wwn1#

appBarItems组件似乎只接受React.Element作为有效输入。您创建的新元素是一个函数:

const AppBarItems: React.Element<IAppBarItem> = () => {...};

分配给AppBarItems的类型也不正确,因为您创建的函数 * 返回 * React.Element,而不是直接返回元素。
解决方法是:

const AppBarItems: React.Element<IAppBarItem> = (
  <div>
   ... dont render a list here, build the actual JSX here...
  </div>
);

但是看起来您正尝试将其作为一个有状态组件,您可以将React.Element看作实际的DOM元素,它还不是一个React组件。
要使其成为React组件,请尝试以下操作:
一个二个一个一个
请注意,我们现在使用<AppBarItem />呈现React组件,并且不创建值为react元素的JS变量。
我鼓励您理解这两种语法之间的区别:

const MyElement = <p>I am a DOM element!</p>;

v/s

const MyComponent = () => <p>I am a component!</p>

用法:

const App = () => {
  return (
    <div>
      <MyComponent />
      {MyElement}
    </div>
  );
}

相关问题