2017-10-13 6 views
0

J'ai une application appelée avec des arguments. À l'heure actuelle, mon menu est toujours chargé dans le menu principal par défaut. Je voudrais pouvoir passer dans un état à Menu.js et commencer avec un menu différent ouvert, au lieu du MainMenu par défaut.Comment puis-je mettre à jour l'état de mon menu uniquement lors du premier rendu de mon composant?

Je pensais que componentWillMount() me permettrait de définir mon état sur un état de menu de mon choix, mais pour une raison quelconque, il ne mettrait pas à jour le contenu rendu. Quand je l'appelle, this.state.Selected devient le nom de menu correct que je veux rendre ... mais il ne rend pas réellement - Il finit par rendre le menu par défaut.

Alors je dois appeler quelque chose d'autre après componentWillMount() pour le rendre réellement?

Landing.js - Appels Menu.js. Je voudrais d'abord rendre le menu 'FileOptions'. Cependant, il est en train de restituer MainMenu.

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

Je pense qu'il y a un bug dans votre fonction de rendu dans Menu. Vous ne pouvez pas simplement changer une chaîne en composant React. si Selected = "FileOptions", vous ne pouvez pas faire et attendez-vous à ce qu'il soit . Je ne suis pas sûr pourquoi il rendra MainMenu, vous pourriez vouloir vérifier ce qui est retourné de 'require ('electron'). Remote.getGlobal ('sharedObject'). HlpOne' – Yiou

+0

le sharedObject rend le contenu de la page et ne gâche pas le menu en haut. En ce moment rend MainMenu ou FileOptions en raison de const {Selected} = this.state. Quand un élément de menu est cliqué, l'état est mis à jour et une fonction est appelée provoquant le rendu du composant. Tout le système de menu fonctionne bien, il doit toujours partir de MainMenu. Était l'espoir de trouver un moyen de démarrer à partir d'un point de menu différent, comme FileOptions – user3622460

Répondre

1

De l'react docs for componentWillMount,

componentWillMount() est invoquée immédiatement avant le montage se produit. Il est appelé avant render(), donc le réglage de l'état de façon synchrone dans cette méthode ne déclenchera pas un nouveau rendu. Évitez d'introduire des effets secondaires ou des abonnements dans cette méthode. C'est le seul hook lifecycle appelé sur le rendu du serveur. Généralement, nous recommandons en utilisant le constructor() à la place.

Update 1

Définissez votre nom de menu sélectionné dans le constructeur et retirez setState de componentWillMount.

Mise à jour 2

@Yiou remarqué que <Selected /> n'est pas un composant.

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

Je ne comprends pas, j'ai l'ensemble constructeur. Si je mets Selected: this.props.menuName à l'intérieur du constructeur - j'obtiens les mêmes résultats. – user3622460

+0

@ user3622460 mise à jour de réponse avec un morceau de code qui pourrait vous aider – bennygenel

+0

Ah, c'est ce que j'avais avant d'introduire componentWillMount. Ne fonctionne pas Si je mets menuName à 'FileOptions', le chargement du menu échouera. Pour une raison quelconque, si je ne passe pas dans MainMenu, il ne chargera aucun menu du tout. – user3622460