首页 > 解决方案 > 重新渲染主组件

问题描述

我的问题的原因是如何从子组件重新加载主组件父组件的数据。

因此,例如以下是主要组件

const App: React.FC = () => {
  const [isReg, setIsReg] = useState(false);
  const [cliente, setCliente] = useState(true);
  
  const [renderAgain, setRenderAgain] = useState(false);

  useEffect(() => {

    getItem("isRegistered").then(res => {
      if (res!=null){
        setIsReg(true);
        getItem("clientType").then(res => {
          if (res=="1"){
            setCliente(true)
          }else{
            setCliente(false)
          }
        })
      }
      else{
        setIsReg(false);
      }
    });

}, [renderAgain]);

return(
<IonApp>
<IonReactRouter>
<IonSplitPane contentId="main" when="(min-width: 4096px)">
      <Menu renderAgain={renderAgain} setRenderAgain={setRenderAgain} />
  <IonRouterOutlet id="main">

    <Route path="/" render={() => isReg ?   ( cliente ?  <HomeCliente setRenderAgain={setRenderAgain}/> : <HomeProveedor setRenderAgain={setRenderAgain}/> ) : <Inicio /> } />
    <Route path="/home" render={() =>  isReg ? (cliente ?  <HomeCliente setRenderAgain={setRenderAgain}/> : <HomeProveedor setRenderAgain={setRenderAgain}/> ): <Inicio /> } ></Route>
    <Route path="/registro" render={() => isReg ?   ( cliente ?  <HomeCliente setRenderAgain={setRenderAgain}/> : <HomeProveedor setRenderAgain={setRenderAgain}/> ) : <Registro /> } />

    <Route path="/ingresar" render={() => isReg ?   ( cliente ?  <HomeCliente setRenderAgain={setRenderAgain}/> : <HomeProveedor setRenderAgain={setRenderAgain}/> ) :<Ingresar setRenderAgain={setRenderAgain} />} /> 
  
    <Route path="/Completarinfo" render={() => <Completarinfo setRenderAgain={setRenderAgain} renderAgain={renderAgain} />}  />
    <Route path="/CompletarRubros" component={CompletarRubros} exact={true}  

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

);
};

在主组件的 useEffect 中可以看到,搜索保存在设备上的数据。验证您是否已注册以及它是什么类型的客户。

这样,如果没有注册,就会渲染 Inicio 组件。它使您可以选择进入或注册。现在,一旦它启动或注册,你必须去 /home,但如果它已登录,则需要再次查看主组件的 useEffect,为此我使用 renderAgain 钩子,说你有从 App 重新执行 useEffect。

const IngresarDatos = (props:{ setRenderAgain:any, setShowLoading:any, setShowAlertUsuarioContraseñaIncorrectos:any,  setShowAlertServerConnection:any, setShowAlertCompletarInfo:any, setShowAlertContraseñaCambiada:any, setShowAlertContraseñaNoIguales:any, setShowAlertBadEmail:any, setShowAlertBadCode:any}) => {
  
    const axios = require('axios');
    const [home, setHome]=useState(false)
  
    const [restaurar, setRestaurar]=useState(0)

    const password = useRef(0)
    const email=useRef("")

    if(home){
      
      props.setRenderAgain(true)
      return(<Redirect push={true} to="/home" />);
     
    }
  
    const validarRestauracion = () => {
      setRestaurar(3)
    }

    const ingresar = () => {
      if((email.current!= null && email.current!= undefined && email.current!="")&& (password.current!=null && password.current!= undefined )){
  
        props.setShowLoading(true)
  
        axios.get(url+"ingresar/"+email.current+"/"+password.current, {timeout: 7000})
        .then((res: { data: any; }) => {
          const resquest = res.data;
          console.log(res.data)
          if(resquest=="usuario y contraseña no válidos"){
            props.setShowLoading(false)
            props.setShowAlertUsuarioContraseñaIncorrectos(true)
  
          }
          else if(resquest[0].picture ==""){
            setItem("isRegistered", resquest[0].user).then(() =>{
                setItem("clientType", resquest[0].clientType).then(() =>{
                  setItem("personalInfoCompleted",false).then(() =>{
                    props.setShowLoading(false)
                    setHome(true)
                  })
                })
              
            });
            
  
          }
          else{
            setItem("isRegistered", email.current).then(() =>{
             
              setItem("fotoPersonal", resquest[0].picture).then(() =>{
                setItem("clientType", resquest[0].clientType).then(() =>{
                  setItem("personalInfoCompleted",true).then(() =>{
                    props.setShowLoading(false)
                    setHome(true)
                  })
                })
              })
            });
          }
        }).catch((err: any) => {
          // what now?
         props.setShowLoading(false)
          props.setShowAlertServerConnection(true)
      })
      }else{
        props.setShowAlertCompletarInfo(true)
      }  
  
    }
    

验证数据后,home 等于 true,因此执行以下操作:

    if(home){   
      props.setRenderAgain(true)
      return(<Redirect push={true} to="/home" />);
    }

它被重定向到主页,问题是如果我不更改renderAgain,除非我刷新浏览器,否则主页不会重新加载。我做对了吗?如何正确地重新加载主要组件,以便检查它应该转到哪个 url?

标签: reactjstypescriptrender

解决方案


不要直接将setState传给props,先在主组件中添加一个函数,再传给props。在主要组件中:

// ...code
const handleRenderAgain = (render: boolean) => setRenderAgain(render);
// ...code
<Menu renderAgain={renderAgain} setRenderAgain={handleRenderAgain} />
// ...rest of the code

推荐阅读