2017-10-13 9 views
0

私は引数で呼び出されるアプリケーションを持っています。今、私のメニューは常にデフォルトのMainMenuにロードされます。 Menu.jsに状態を渡して、デフォルトのMainMenuの代わりに別のメニューを開いて起動したいと考えています。コンポーネントを初めてレンダリングするときにのみ、メニューの状態を更新するにはどうすればよいですか?

私はcomponentWillMount()を使って自分の状態を自分の選択したメニュー状態にすることができたと思いましたが、何らかの理由でレンダリングされたコンテンツを更新していません。私がそれを呼び出すと、this.state.Selectedはレンダリングしたい正しいメニュー名になりますが、実際にはレンダリングされません - デフォルトメニューのレンダリングが終了します。

実際にレンダリングするには、componentWillMount()の後に別のものを呼び出す必要がありますか?

Landing.js - Menu.jsを呼び出します。私は 'FileOptions'メニューを最初にレンダリングしたいと思います。しかし、現在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

メニューのレンダリング機能にバグがあると思います。文字列をReactコンポーネントに変更することはできません。 Selected = "FileOptions"の場合、は実行できず、になると予想されます。私はMainMenuをレンダリングする理由がわからないので、 'require( 'electron')から返されたものをチェックしたいかもしれません。remote.getGlobal( 'sharedObject').hlpOne' – Yiou

+0

sharedObjectはページコンテンツをレンダリングし、メニューアップ。今すぐは、const {Selected} = this.stateのためにMainMenuまたはFileOptionsをレンダリングします。メニュー項目がクリックされると、状態が更新され、関数が呼び出されてコンポーネントが再レンダリングされます。メニューシステム全体がうまく動作し、常にMainMenuから始める必要があります。私は理解していないFileOptions – user3622460

答えて

1

react docs for componentWillMountから実装が発生する前に、

componentWillMount()が直ちに呼び出されます。 これはrender()の前に呼び出されます。したがって、このメソッドで状態を同期して設定すると、 は再レンダリングをトリガーしません。このメソッドでは、 の副作用またはサブスクリプションを導入しないでください。これは、サーバーレンダリング時に呼び出される唯一の ライフサイクルフックです。通常、代わりにconstructor()を使用して をお勧めします。

アップデート1

コンストラクタ内であなたの選択したメニュー名を設定し、componentWillMountからSETSTATEを削除します。

アップデート2

@Yiouは<Selected />が構成要素ではないことに気づきました。

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

のような別のメニューポイントから開始する方法を見つけることを望んでいた、私はコンストラクタを設定している。選択したもの:this.props.menuNameをコンストラクタ内に設定すると、同じ結果が得られます。 – user3622460

+0

@ user3622460あなたに役立つかもしれないコードを更新しました – bennygenel

+0

ああ、それはcomponentWillMountを導入する前のものです。動作しません。 menuNameを 'FileOptions'に設定すると、メニューが読み込まれなくなります。何らかの理由で、私がMainMenuを渡さないと、メニューをロードすることができません。 – user3622460

関連する問題