は親

2017-05-28 6 views
1

から子コンポーネントの関数を呼び出すときに材料-UIの引き出しは、私はボタンをクリックしたときに私はここには親

import React, { Component } from 'react'; 

class Child extends Component { 
    state = { } 
    onAlert =()=> 
     alert("hey"); 
    render() { 
     return (
      <div> IM kid</div> 
     ); 
    } 
} 

export default Child; 

ようApp.js

import React, { Component } from 'react'; 
import logo from './logo.svg'; 
import './App.css'; 
import Child from './child'; 

class App extends Component { 
    render() { 
    return (
     <div className="App"> 
     <div className="App-header"> 
      <img src={logo} className="App-logo" alt="logo" /> 
      <h2>Welcome to React</h2> 
     </div> 
     <p className="App-intro"> 
      To get started, edit <code>src/App.js</code> and save to reload. 
     </p> 
     <Child ref={instance => { this.child = instance; }}/> 
      <button onClick={() => { this.child.onAlert(); }}>Click</button> 
     </div> 
    ); 
    } 
} 

export default App; 

と子コンポーネントのサンプルコードを持ってworingないリアクトApp.jsで私は期待される出力を得ることができます つまり、私は子の関数onAlert()を呼び出すことができます

私は同じシナリオをmaterial-uiで使っていますERE私はツールバーコンポーネント

から引き出しコンポーネントをトリガーする必要があり、私のコードは、コードの下にTitlebar.jsのようなものです、ここで

import React, { Component } from 'react'; 
import PropTypes from 'prop-types'; 
import Toolbar from 'material-ui/Toolbar' 
import AppBar from 'material-ui/AppBar'; 
import Typography from 'material-ui/Typography'; 
import IconButton from 'material-ui/IconButton'; 
import MenuIcon from 'material-ui-icons/Menu'; 

import { withStyles, createStyleSheet } from 'material-ui/styles'; 
import Child from './child'; 



const styleSheet = createStyleSheet('Titlebar',() => ({ 

    root: { 
     position: 'relative', 
     width: '100%', 
    }, 
    appBar: { 
     position: 'relative', 
    }, 
    flex: { 
     flex: 1, 
    } 
})); 

class TitleBar extends Component { 
    render() { 
     const classes = this.props.classes; 
     return (
      <div className={classes.root}> 
       <AppBar className={classes.appBar}> 
        <Toolbar> 
         <IconButton contrast onClick={() => { this.child.handleLeftOpen(); }}> 
          <MenuIcon /> 
         </IconButton> 
         <Typography type="title" colorInherit className={classes.flex}>Productivity Dashboard</Typography> 
        </Toolbar> 
       </AppBar> 
       <Child ref={instance => { this.child = instance; }}/> 
      </div> 
     ) 
    } 
} 

TitleBar.PropTypes={ 
    classes:PropTypes.object.isRequired, 
} 

export default withStyles(styleSheet)(TitleBar); 

とChild.jsが

import React, { Component } from 'react'; 
import { withStyles, createStyleSheet } from 'material-ui/styles'; 
import Drawer from 'material-ui/Drawer'; 
import List, { ListItem, ListItemIcon, ListItemText } from 'material-ui/List'; 
import Divider from 'material-ui/Divider'; 
import InboxIcon from 'material-ui-icons/Inbox'; 
import DraftsIcon from 'material-ui-icons/Drafts'; 
import StarIcon from 'material-ui-icons/Star'; 
import SendIcon from 'material-ui-icons/Send'; 
import MailIcon from 'material-ui-icons/Mail'; 
import DeleteIcon from 'material-ui-icons/Delete'; 
import ReportIcon from 'material-ui-icons/Report'; 

const styleSheet = createStyleSheet('Child', { 
    list: { 
    width: 250, 
    flex: 'initial', 
    }, 
    listFull: { 
    width: 'auto', 
    flex: 'initial', 
    }, 
}); 
class Child extends Component { 
    state = { 
    open: { 
     top: false, 
     left: false, 
     bottom: false, 
     right: false, 
    }, 
    } 
handleLeftOpen =() =>{ 
      console.log("im here") 
      this.toggleDrawer('left', true); 
     } 
     handleLeftClose =() => this.toggleDrawer('left', false); 
    toggleDrawer = (side, open) => { 
    const drawerState = {}; 
    drawerState[side] = open; 
    this.setState({ open: drawerState }); 
    }; 
    render() { 
     const classes=this.props.classes; 
     return (
      <Drawer 
      open={this.state.open.left} 
      onRequestClose={this.handleLeftClose} 
      onClick={this.handleLeftClose} 
     > 
     <List className={classes.list} disablePadding> 
      <ListItem button> 
      <ListItemIcon> 
      <InboxIcon /> 
      </ListItemIcon> 
      <ListItemText primary="Inbox" /> 
     </ListItem> 
     <ListItem button> 
      <ListItemIcon> 
      <StarIcon /> 
      </ListItemIcon> 
      <ListItemText primary="Starred" /> 
     </ListItem> 
     <ListItem button> 
      <ListItemIcon> 
      <SendIcon /> 
      </ListItemIcon> 
      <ListItemText primary="Send mail" /> 
     </ListItem> 
     <ListItem button> 
      <ListItemIcon> 
      <DraftsIcon /> 
      </ListItemIcon> 
      <ListItemText primary="Drafts" /> 
     </ListItem> 
     </List> 
     <Divider /> 
     <List className={classes.list} disablePadding> 
      <ListItem button> 
      <ListItemIcon> 
      <MailIcon /> 
      </ListItemIcon> 
      <ListItemText primary="All mail" /> 
     </ListItem> 
     <ListItem button> 
      <ListItemIcon> 
      <DeleteIcon /> 
      </ListItemIcon> 
      <ListItemText primary="Trash" /> 
     </ListItem> 
     <ListItem button> 
      <ListItemIcon> 
      <ReportIcon /> 
      </ListItemIcon> 
      <ListItemText primary="Spam" /> 
     </ListItem> 
     </List> 
       </Drawer> 
     ); 
    } 
} 

export default withStyles(styleSheet)(Child); 
を下回っている私の子コンポーネントのコード私の親コンポーネントであります

ここでは、TiltlbarコンポーネントのIconButtonをクリックしたときに、親からhandleLeftOpen()関数を呼び出しています。予想される出力が得られません。私は

Uncaught TypeError: Cannot read property 'handleLeftOpen' of null 
    at onClick (http://localhost:3000/static/js/bundle.js:90993:50) 
    at Object.ReactErrorUtils.invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:17236:17) 
    at executeDispatch (http://localhost:3000/static/js/bundle.js:17019:22) 
    at Object.executeDispatchesInOrder (http://localhost:3000/static/js/bundle.js:17042:6) 
    at executeDispatchesAndRelease (http://localhost:3000/static/js/bundle.js:16430:23) 
    at executeDispatchesAndReleaseTopLevel (http://localhost:3000/static/js/bundle.js:16441:11) 
    at Array.forEach (native) 
    at forEachAccumulated (http://localhost:3000/static/js/bundle.js:17339:10) 
    at Object.processEventQueue (http://localhost:3000/static/js/bundle.js:16644:8) 
    at runEventQueueInBatch (http://localhost:3000/static/js/bundle.js:24266:19) 

コードをチェックして、何が

を変更する必要がある場合は私に知らせてください、私のコンソールに以下のようなエラーを取得しています

答えて

1

ここでの違いは、あなたの最初の例では、あなたがエクスポートすることです:

export default Child; 

export default withStyles(styleSheet)(Child); 

これが飾らを返します。エクスポート2番目の例では

ref要素は、この装飾されたコンポーネントに置かれ、子コンポーネントには置かれません。この問題を解決するために、装飾されたコンポーネントはinnerRefというプロパティを受け入れますので、自分のコンポーネントにrefを渡すことができます。

<Child innerRef={instance => { this.child = instance; }}/> 

<Child ref={instance => { this.child = instance; }}/> 

:だから、あなたが変更にこれを解決するために