2017-10-13 3 views
0

Ich habe eine Anwendung, die mit Argumenten aufgerufen wird. Im Moment lädt mein Menü immer das Standard MainMenu. Ich möchte in der Lage sein, einen Status zu Menu.js zu übergeben und mit einem anderen geöffneten Menü anstelle des Standard-MainMenu zu beginnen.Wie kann ich den Status meines Menüs nur bei der ersten Wiedergabe meiner Komponente aktualisieren?

Ich dachte componentWillMount() würde mir ermöglichen, meinen Zustand zu einem Menü-Status meiner Wahl zu setzen, aber aus welchen Gründen auch immer es den gerenderten Inhalt nicht aktualisiert. Wenn ich es nenne, wird this.state.Selected der richtige Menüname, den ich rendern möchte ... aber es wird nicht wirklich gerendert - Es endet mit dem Rendern des Standardmenüs.

Also muss ich nach componentWillMount() etwas anderes aufrufen, um es tatsächlich zu rendern?

Landing.js - ruft Menu.js auf. Ich möchte zuerst das Menü 'FileOptions' rendern. Zurzeit wird jedoch MainMenu gerendert.

import React, { Component } from 'react' 
import sass from '../scss/application.scss' 
import PropTypes from 'prop-types' 
import Header from './Header' 
import Menu from './Menu' 
import HelpFile from './HelpFile' 



class Landing extends Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      helpFileName: 'Mainmenu', 
      menuName: 'FileOptions', 
     } 
     } 

    handleHelpChange(helpFileName) { 
     this.setState({helpFileName}); 
    } 

    handleMenuClick(menuName) { 
     this.setState({menuName}); 
    } 

    componentWillMount() { 
     let hlpString = require('electron').remote.getGlobal('sharedObject').hlpOne; 
     if (hlpString != null && hlpString != '.') 
     { 
      this.setState({ 
       helpFileName: hlpString 
      });ss 
     } 
    } 

    render() { 

     return (
      <div> 
       <div> 
        <Header /> 
       </div> 
       <br /><br /> 
       <div className="mainMenuDiv"> 
        <Menu handleHelpChange={this.handleHelpChange.bind(this)} menuName={this.state.menuName}/> 
       </div> 
       <div className="mainContainerDiv"> 
        <HelpFile name={this.state.helpFileName}/> 
       </div> 
      </div> 

     ) 
    } 
} 


export default Landing; 

Menu.js

import React, { Component } from 'react' 
import sass from '../scss/application.scss' 
import PropTypes from 'prop-types' 



class Menu extends Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      Selected: props.menuName,  // reads FileOptions, but still renders MainMenu 
      name: '' 
     } 
     } 

    handleChange(name) { 
     this.setState({ 
      name: name 
     }); 
    } 

    handleClick(e, num) { 
     this.setState({ 
      name: num 
      },() => { 
      let helpFileName = num; 
      helpFileName = helpFileName.toLowerCase().trim(); 
      //Cap the first letter in the name and add the rest of the name 
      helpFileName = helpFileName.charAt(0).toUpperCase() + helpFileName.substr(1); 
      this.props.handleHelpChange(helpFileName); 
      }); 
     } 

    handleMenuClick(e, num, opt) { 
     this.setState({ 
      name: num, 
      Selected: opt 
      },() => { 
      let helpFileName = num; 
      helpFileName = helpFileName.toLowerCase().trim(); 
      //Cap the first letter in the name and add the rest of the name 
      helpFileName = helpFileName.charAt(0).toUpperCase() + helpFileName.substr(1); 
      this.props.handleHelpChange(helpFileName); 
      }); 
     } 

    render() { 
     const MainMenu =() => (
      <div> 
       <button 
        label="File Options" 
        //onClick={() => this.setState({ Selected: FileOptions })} 
        onClick={(e) => this.handleMenuClick(e, 'Fileopt', FileOptions)} 
        className="aMenuButton" 
       >FILE OPTIONS</button> 
       <button 
        label="Setup Options" 
        onClick={(e) => this.handleMenuClick(e, 'Setupopt', SetUpOptions)} 
        className="aMenuButton" 
       >SETUP OPTIONS</button> 
       <button 
        label="Lumber Options" 
        onClick={(e) => this.handleMenuClick(e, 'Lumberopt', MoreOptions)} 
        className="aMenuButton" 
       >MORE OPTIONS</button> 
       <button 
        label="Main Menu" 
        onClick={(e) => this.handleClick(e, 'Mainmenu')} 
        className="aPrevButton" 
       >MAIN MENU</button> 
      </div> 
     ); 

     const FileOptions =() => (
      <div> 
       <button 
        label="Option One" 
        onClick={(e) => this.handleClick(e, 'Option One')} 
        className="aMenuButton" 
       >Option One</button> 
       <button 
        label="Option Two" 
        onClick={(e) => this.handleClick(e, 'Option Two')} 
        className="aMenuButton" 
       >Option Two</button> 
       <button 
        label="Option Three" 
        onClick={(e) => this.handleClick(e, 'Option Three')} 
        className="aMenuButton" 
       >Option Three</button> 
       <button 
        label="Option Four" 
        onClick={(e) => this.handleClick(e, 'Option Four')} 
        className="aMenuButton" 
       >Option Four</button> 
       <button 
        label="Previous Menu" 
        onClick={() => this.setState({ Selected: MainMenu })} 
        className="aPrevButton" 
       >PREVIOUS MENU</button> 
      </div> 
     ); 

     const SetUpOptions =() => (
      <div> 
       <button 
        label="Option One" 
        onClick={(e) => this.handleClick(e, 'Option One')} 
        className="aMenuButton" 
       >Option One</button> 
       <button 
        label="Option Two" 
        onClick={(e) => this.handleClick(e, 'Option Two')} 
        className="aMenuButton" 
       >Option Two</button> 
       <button 
        label="Option Three" 
        onClick={(e) => this.handleClick(e, 'Option Three')} 
        className="aMenuButton" 
       >Option Three</button> 
       <button 
        label="Previous Menu" 
        onClick={() => this.setState({ Selected: MainMenu })} 
        className="aPrevButton" 
       >PREVIOUS MENU</button> 
      </div> 
     ); 

     const MoreOptions =() => (
      <div> 
       <button 
        label="Option One" 
        onClick={(e) => this.handleClick(e, 'Option One')} 
        className="aMenuButton" 
       >Option One</button> 
       <button 
        label="Option Two" 
        onClick={(e) => this.handleClick(e, 'Option Two')} 
        className="aMenuButton" 
       >Option Two</button> 
       <button 
        label="Option Three" 
        onClick={(e) => this.handleClick(e, 'Option Three')} 
        className="aMenuButton" 
       >Option Three</button> 
       <button 
        label="Option Four" 
        onClick={(e) => this.handleClick(e, 'Option Four')} 
        className="aMenuButton" 
       >Option Four</button> 
       <button 
        label="Previous Menu" 
        onClick={() => this.setState({ Selected: MainMenu })} 
        className="aPrevButton" 
       >PREVIOUS MENU</button> 
      </div> 
     ); 

     const { Selected } = this.state; 

     return (
      <div> 
       <div className="menuButtons"> 
        {Selected === 'MainMenu' ? <MainMenu /> : <Selected /> } 
       </div> 
      </div> 
     ) 
    } 
} 

Menu.propTypes = { 
    handleHelpChange: PropTypes.func, 
    name: PropTypes.string, 
    menuName: PropTypes.string 
} 


export default Menu; 
+1

Ich denke, es gibt einen Fehler in der Render-Funktion im Menü. Sie können eine Zeichenfolge nicht einfach in Komponente reaktiv ändern. Wenn Selected = "FileOptions" ausgewählt ist, können Sie nicht ausführen und erwarten, dass es ist. Ich bin mir nicht sicher, warum MainMenu gerendert wird, vielleicht möchten Sie überprüfen, was von 'require ('electron') zurückgegeben wird. Remote.getGlobal ('sharedObject'). HlpOne' – Yiou

+0

Die sharedObject rendert den Seiteninhalt und führt nicht zu Fehlern Menü auf. Gerade jetzt rendert MainMenu oder FileOptions wegen const {Selected} = this.state. Wenn auf ein Menüelement geklickt wird, wird der Status aktualisiert und eine Funktion aufgerufen, die bewirkt, dass die Komponente erneut gerendert wird. Das gesamte Menüsystem funktioniert einwandfrei, es muss immer nur von MainMenu aus gestartet werden. Hoffte, einen Weg zu finden, von einem anderen Menüpunkt zu starten, wie FileOptions – user3622460

Antwort

1

Vom react docs for componentWillMount,

componentWillMount() wird sofort aufgerufen vor der Montage erfolgt. Es wird vor render() aufgerufen, daher wird das Setzen des Status synchron in dieser Methode kein erneutes Rendering auslösen. Vermeiden Sie die Einführung von Nebenwirkungen oder Abonnements in dieser Methode. Dies ist der einzige Lebenszyklus-Hook, der beim Server-Rendering aufgerufen wird. Im Allgemeinen empfehlen wir stattdessen mit der constructor().

aktualisieren 1

Legen Sie Ihre ausgewählten Menünamen im Konstruktor und entfernen setState von componentWillMount.

aktualisieren 2

@Yiou bemerkt, dass <Selected /> nicht Bestandteil ist.

class Menu extends Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
     Selected: props.menuName || '', 
     name: '' 
     } 
    } 

    // .... 

    render() { 

    // after you created all your menu constant implement a switch to select 
    // which menu is going to render 
    const { Selected } = this.state; 
    let SelectedMenu; 
    switch(Selected) { 
     case 'MainMenu': 
     SelectedMenu = MainMenu; 
     break; 
     case 'FileOptions': 
     SelectedMenu = FileOptions; 
     break; 
     default: 
     SelectedMenu = MainMenu; 
     break; 
    } 

    return (
     <div> 
      <div className="menuButtons"> 
       {SelectedMenu()} 
      </div> 
     </div> 
    ) 
    }  
} 
+0

Ich verstehe nicht, ich habe den Konstruktor gesetzt. Wenn ich Selected: this.props.menuName innerhalb des Konstruktors einstelle - bekomme ich die gleichen Ergebnisse. – user3622460

+0

@ user3622460 aktualisierte Antwort mit einem Stück Code, der Ihnen helfen könnte – bennygenel

+0

Ah, das war, was ich vor der Einführung von ComponentWillMount hatte. Funktioniert nicht. Wenn ich menuName auf 'FileOptions' setze, kann das Menü nicht geladen werden. Aus welchem ​​Grund auch immer, wenn ich das MainMenu nicht übergebe, kann es überhaupt kein Menü laden. – user3622460

Verwandte Themen