【问题标题】:Conditional routing based on boolean variable基于布尔变量的条件路由
【发布时间】:2021-01-22 19:55:27
【问题描述】:

我对这条线有疑问:

<Route path="/" render={() => isReg ? <Registro />: <Home /> } />

我得到的是这样的:

JSX 元素类型'元素 | undefined' 不是构造函数 对于 JSX 元素。类型“未定义”不可分配给类型 '元素 |空值'。 TS2605

我要做的是确认用户是否注册了isReg变量,如果已经注册,则必须显示“/home”,否则显示“/Registro”

但我无法修复那个条件路由语句。我将不胜感激。提前致谢。

const App: React.FC = () => {
  const [isReg, setIsReg] = useState(false);

  useEffect(() => {
    if(getItem("isRegistered2")==null){
    console.log(getItem("isRegistered2"));
    setIsReg(true);
  }
  else{
    setIsReg(false);
  }
}, []);

return(
<IonApp>
<IonReactRouter>
<IonSplitPane contentId="main" when="(min-width: 4096px)">
      <Menu />
  <IonRouterOutlet id="main">
  <Route path="/" render={() => isReg ? <Registro />: <Home /> } />
    <Route path="/registro" component={Registro} exact={true}></Route>
    <Route path="/ingresar" component={Ingresar} exact={true}></Route>
    <Route path="/MisServicios" component={MisServicios} exact={true}></Route>
    <Route path="/Favoritos" component={Favoritos} exact={true}></Route>
    <Route path="/HistorialServicios" component={HistorialServicios} exact={true}></Route>
    <Route path="/Completarinfo" component={Completarinfo} exact={true} />
    <Route path="/Login" component={Login} exact={true} />


    <Route path="/tab2" component={Tab2} exact={true} />



  </IonRouterOutlet>
  </IonSplitPane>
</IonReactRouter>
</IonApp>

);
};

export default App; 

英语

我认为问题在于 Home 组件。因为如果我为另一个组件换家,我没有问题。我在 Home 中看到的不同之处在于它有一个 Modal。

Home.tsx

const Home = () => {
  const [showModal, setShowModal] = useState({ isOpen: false });
  const [retVal, setRetVal] = useState(null);
  const [count, setCount] = useState(0);

  const [login, setLogin]=useState(0);

  const axios = require('axios');

  const data2 = getLocation();

  if(getItem("isRegistered")!=null){
    console.log(getItem("isRegistered"));
    setLogin(1);
  }
  else{
    setLogin(0);
  }

  data2.then((value)=>{
    
    console.log(url+value);
    axios.get(url+value).then((resp: { data: any; }) => {

      console.log(resp.data);
    });  
  
  })
  
  if(login===1){
    return (
      <IonPage>
        <IonHeader>
          <IonToolbar>
            <IonGrid>
              <IonRow id="header">
                <IonCol id="columna" size="1.5"><IonButtons ><IonMenuButton /> </IonButtons></IonCol>
                <IonCol id="columna2" ><Busqueda /></IonCol>
                <IonCol id="columna3" size="2"> 
                  <IonChip  onClick={() => {  setShowModal({ isOpen: true});  setCount(0)}}id="user" >
                    <IonIcon icon={person} id="foto-usuario"/>
                  </IonChip>
                 </IonCol>
              </IonRow>
            </IonGrid>
          </IonToolbar>
        </IonHeader>
        
        <IonContent className="ion-padding">
        <IonModal
            animated={true}
            isOpen={showModal.isOpen}
            onDidDismiss={() => setShowModal({ isOpen: false })}
          >
            <MyModal 
               tipo={count}
               onClose={(value: React.SetStateAction<null>) => {
                setShowModal({ isOpen: false });
                value ? setRetVal(value) : setRetVal(null);
              }} 
            />  
          </IonModal>

          <IonGrid>
          <IonRow>
          <IonCol>
            <div id="contenedor-prueba">
            <IonChip className="boton-generales"  onClick={() => {  setShowModal({ isOpen: true});  setCount(1)}}>
              <IonLabel ><small>Emergencias</small></IonLabel>
              <IonAvatar> <img src={"./assets/icon/sirena.png"} className="imagen-boton-principal"/></IonAvatar> 
            </IonChip>
            </div>
          </IonCol>
          <IonCol>
          <div id="contenedor-prueba">
            <IonChip className="boton-generales"  onClick={() => {  setShowModal({ isOpen: true});  setCount(2)}}>
              <IonLabel><small>Categorías</small></IonLabel>
              <IonAvatar> <img src={"./assets/icon/servicio.png"} className="imagen-boton-principal"/></IonAvatar> 
            </IonChip>
            </div>
          </IonCol>
          <IonCol>
          <div id="contenedor-prueba">
            <IonChip className="boton-generales"  onClick={() => {  setShowModal({ isOpen: true});  setCount(3)}}>
              <IonLabel><small>Programado</small></IonLabel>
              <IonAvatar> <img src={"./assets/icon/time.png"} className="imagen-boton-principal"/></IonAvatar> 
            </IonChip>
            </div>
          </IonCol>
          </IonRow>
          </IonGrid>

          <ExploreContainer  />
        </IonContent>
      </IonPage>
  );

  }
  
};


const MyModal: React.FC<{onClose: any; tipo: number;}> = ({ onClose, tipo }) => {
  
  if(tipo===0){
    return (
      <>
      <IonHeader>
        <IonToolbar>
        <IonIcon icon={arrowBack} onClick={() => onClose(null)} slot="start" id="flecha-volver">  </IonIcon>

        </IonToolbar>
      </IonHeader>
      <IonContent>
        <div id="contenedor-central">
          <br></br>
          <IonButton href="/ingresar" id="botoningresoregistro">INGRESAR</IonButton>
          <IonButton href="/registro" id="botoningresoregistro">REGISTRARSE</IonButton>
        </div>
      </IonContent>
    </>
    );
  }
  if(tipo===1){
    return (
      <>
      <IonHeader>
        <IonToolbar>
        <IonIcon icon={arrowBack} onClick={() => onClose(null)} slot="start" id="flecha-volver">  </IonIcon>

        </IonToolbar>
      </IonHeader>
      <IonContent>
        <div id="contenedor-central">
          <strong>Emergencias</strong>
        </div>
      </IonContent>
    </>
    );
  }
  if(tipo===2){
    return (
      <>
      <IonHeader>
        <IonToolbar>
        <IonIcon icon={arrowBack} onClick={() => onClose(null)} slot="start" id="flecha-volver">  </IonIcon>

        </IonToolbar>
      </IonHeader>
      <IonContent>
        <div id="contenedor-central">
          <strong>Categorías</strong>
        </div>
      </IonContent>
    </>
    );
  }
  else{
    return (
      <>
      <IonHeader>
        <IonToolbar>
        <IonIcon icon={arrowBack} onClick={() => onClose(null)} slot="start" id="flecha-volver">  </IonIcon>

        </IonToolbar>
      </IonHeader>
      <IonContent>
        <div id="contenedor-central">
          <strong>Programados</strong>
        </div>
      </IonContent>
    </>
    );
  }
 
};


class Modal extends Component{
  constructor(props: Readonly<{}>) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    console.log('Se hizo click');
  }
  render() {
    return <button onClick={this.handleClick}>Clickéame</button>;
  }
}


class Busqueda extends Component{

  Buscar = () =>{
    var input=(document.getElementById("busqueda") as HTMLTextAreaElement).value;
  
    if(input==="hola"){
      console.log("hola perri");
    }
  }
   render(){
    return(<IonSearchbar type="text" placeholder="¿Qué servicios buscas?" onIonInput={this.Buscar} id="busqueda"></IonSearchbar>);
       }
    
  };

  export default Home;

【问题讨论】:

    标签: javascript reactjs ionic-framework routes


    【解决方案1】:

    定义一个处理条件渲染的新组件。 isReg 状态不应位于 App.js 中。

    AppReg.js

    const AppReg: React.FC = () => {
      const [isReg, setIsReg] = useState(null);
    
      useEffect(() => {
        if (getItem('isRegistered2') == null) {
          console.log(getItem('isRegistered2'));
          setIsReg(true);
        } else {
          setIsReg(false);
        }
      }, []);
    
      if (isReg == null) {
        return <Loader />;
      }
    
      if (isReg === true) {
        return <Registro />;
      } else {
        return <Home />;
      }
    };
    
    export default AppReg;
    

    App.js

    const App: React.FC = () => {
      return (
        <IonApp>
          <IonReactRouter>
            <IonSplitPane contentId="main" when="(min-width: 4096px)">
              <Menu />
              <IonRouterOutlet id="main">
                <Route path="/" component={AppReg} />
                <Route path="/registro" component={Registro} exact={true}></Route>
                <Route path="/ingresar" component={Ingresar} exact={true}></Route>
                <Route path="/MisServicios" component={MisServicios} exact={true}></Route>
                <Route path="/Favoritos" component={Favoritos} exact={true}></Route>
                <Route path="/HistorialServicios" component={HistorialServicios} exact={true}></Route>
                <Route path="/Completarinfo" component={Completarinfo} exact={true} />
                <Route path="/Login" component={Login} exact={true} />
    
                <Route path="/tab2" component={Tab2} exact={true} />
              </IonRouterOutlet>
            </IonSplitPane>
          </IonReactRouter>
        </IonApp>
      );
    };
    
    export default App;
    

    更新:Home组件默认情况下需要返回null。

    【讨论】:

    • 谢谢,但我仍然有返回语句(在 AppReg.tsx 中看起来问题出在 Home 组件):JSX 元素类型'元素 | undefined' 不是 JSX 元素的构造函数。类型“未定义”不可分配给类型“元素 |空值'。 TS2605
    • 这很奇怪。你也实现了加载器组件吗?如果没有,请尝试在此处返回 null 以进行测试。返回 home 组件为 => 将 返回为 ReactElement。否则, Home 将返回未定义,这似乎是问题所在。尝试从 Home 返回 null 来测试。
    • 啊!刚刚看了 Home 组件。如果(登录 === 1),您只会返回一些东西。添加 else return null 应该可以解决问题。我可以更新我的答案以反映这一点。让我知道。
    • 我更新了我的答案,这样在访问这个帖子时没有人会感到困惑。
    • 先生,在 Home 元素中,getItem() 是无限执行的。你知道为什么吗?因为我得到:未捕获的错误:重新渲染太多。 React 限制渲染次数以防止无限循环。
    【解决方案2】:

    像这样使用它:

    像这样初始化未定义的状态:

    const [isReg, setIsReg] = useState();
    

    然后像这样动态创建路由:

    {isReg != undefined && <Route path="/" render={() => isReg ? <Registro />: <Home/>} />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-04
      • 2020-01-12
      • 2019-05-12
      • 2019-04-08
      • 2021-04-10
      相关资源
      最近更新 更多