Lassen Sie mich die Ursache des Problems im Detail beschreiben.
Jetzt gibt es drei Komponenten (vorläufig mit a, b, c bezeichnet), um eine Benutzerauthentifizierungsfunktion zu implementieren.
Die a-Komponente ist die übergeordnete Komponente (im Vergleich zu b und c gibt es eine übergeordnete Komponente außerhalb der a-Komponente), die für den Empfang der von der übergeordneten Komponente übergebenen Authentifizierungsinformationen des Benutzers verantwortlich ist. In der b-Komponente füllt der Benutzer aus Die Informationen und die c-Komponente stellen den Authentifizierungsstatus des Benutzers dar (nicht zertifiziert, geprüft, zertifiziert, Zertifizierung fehlgeschlagen, entsprechende Status sind 0, 1, 2, -1).
Wenn die Benutzerauthentifizierung fehlschlägt, gibt es in Komponente c eine Schaltfläche, die dem Benutzer eine erneute Authentifizierung ermöglicht (Komponenten b und c wechseln).
Das dachte ich mir, als ich es zum ersten Mal schrieb:
Extrahieren Sie einen Status in die a-Komponente (vorläufig anzeigen). Der Wert von show wird anhand des von der a-Komponente weitergegebenen Authentifizierungsstatus (Requisiten) bestimmt. Ändern Sie ihn durch show . Welche Komponente angezeigt werden soll.
Wenn die Benutzerauthentifizierung fehlschlägt, klicken Sie in Komponente c auf „Erneute Authentifizierung“, ändern Sie den Status der übergeordneten Komponentenanzeige über die Rückruffunktion und schließen Sie den Wechsel zwischen den Komponenten b und c ab.
Das Problem tritt in dieser Show auf (vorläufig zeigt „true“ Komponente b an und „false“ zeigt Komponente c an). Der Standardwert von „show“ ist „true“ (ermöglicht dem Benutzer die Eingabe von Informationen).
Ich ändere den Status der Anzeige in „componentWillReceiveProps“ der Komponente a (didMount kann keine Requisiten abrufen und der Status kann beim Rendern nicht manipuliert werden).
Unabhängig davon, ob der Benutzer authentifiziert ist oder nicht, wird beim Laden von Komponente a standardmäßig Komponente b angezeigt, da „componentWillReceiveProps“ nicht aufgerufen wurde. Die C-Komponente wird erst angezeigt, wenn die Seite aktualisiert wird.
Die Lösung, die mir jetzt einfällt, besteht darin, eine Komponente die Daten abrufen zu lassen und dann den Status der Show zu ermitteln. Ich möchte die Experten fragen: Gibt es eine bessere Möglichkeit, mir bei der Erreichung dieser Funktion zu helfen?
Bitte fügen Sie ein Bild hinzu, um es deutlich zu sehen
a:
c:
应该有一个组件去决定是否要进行用户认证,如果你想让登录组件全部包揽这个逻辑,那你需要一个加载状态,刚开始的时候处于加载中,什么都不显示。所谓加载就是决定是否要认证(发API请求等等),加载完毕后就可以决定是否要认证。
我100%保证
componentDidMount()
是可以拿到props参数的,通过 this.props 获取,但是componentDidMount() 只在组件创建时调用一次,通常情况下如果要加载数据就在 componentDidMount() 里执行。show为什么要是a组件的state?你把show当作render函数中的一个局部变量就行了。
假定a组件从props里传递过来的认证状态变量命名为 auth,你的 a 组件render方法可以这样写:
========= 更新 =========
第一次没看到你的C组件居然还有一个回调箭头来改变A组件的show!
对,这一步也是错误的设计。
A组件得到的认证信息是A组件的父组件传递下来的,那么这个show就应该要唯一依赖于这一个信息的,C组件具有改变这个认证信息的功能,那么,A组件有义务把这个改变通知给A组件的父组件,而不是私自地悄么声地改变自己组件的state,即你在这里设定的show这个state,就草草了事。试想,这个时候,A组件得到的props是认证失败,渲染了C组件,C组件有重新认证的功能,用户重新认证成功,C组件又通知A组件认证成功了,这个时候A组件要相信谁?props和state就不同步了!更惨的是A组件的父组件,他还傻乎乎地以为自己拿到的是正确的信息,还通过props告诉A组件,用户认证失败啦,殊不知A组件已经串通他底下的小弟,把认证信息都给改了!倘若这个时候A组件有个兄弟叫A2组件,A2也通过props从他们共同的父组件接收认证信息,那就会出现A和底下一帮家伙悄悄重新认证了,而A的父亲和兄弟还蒙在鼓里,页面显示就不一致啦!
正确的设计是,A组件在接收到C组件重新认证成功的事件通知,需要把这个通知继续往上传递,告诉A组件的父组件,父组件接收到这个事件,改变他自己的状态,进而改变传递给A组件的props,A组件props改变,导致A组件重绘,从而replace C with B。
认证信息只能保存一份,你的例子里,认证信息放在A组件的父组件里,因此,要修改这个认证信息,也应该在A组件的父组件里完成。因此,这个show其实只是一个根据props产生的中间变量,根本无需设计成A的state。
如果你用redux就没有这个疑惑了。