2017-08-25 33 views
0

我似乎无法正确传递此处理程序。 TabItem最终以undeClick定义。传递处理程序结果未定义

SearchTabs

export default class SearchTabs extends Component { 
constructor(props) { 
    super(props) 
    const breakpoints = { 
     [SITE_PLATFORM_WEB]: { 
     displayGrid: true, 
     autoFocus: true, 
     }, 
     [SITE_PLATFORM_MOBILE]: { 
     displayGrid: false, 
     autoFocus: false, 
     }, 
    }; 

    this.state = { 
     breakpoints, 
     filters: null, 
     filter: null, 
     isDropdownOpen: false, 
     selectedFilter: null, 
     tabs: null, 
    }; 

    this.tabChanged = this.tabChanged.bind(this); 
    this.closeDropdown = this.closeDropdown.bind(this); 
    } 
    ... more code 

    createTabs(panels) { 
     if(!panels) return; 
     const tabs = panels.member.map((panel, idx) => { 

      const { selectedTab } = this.props; 
      const { id: panelId, headline } = panel; 
      const url = getHeaderLogo(panel, 50); 
      const item = url ? <img src={url} alt={headline} /> : headline; 

      const classname = classNames([ 
      searchResultsTheme.tabItem, 
      (idx === selectedTab) ? searchResultsTheme.active : null, 
      ]); 

      this.renderFilters(panel, idx, selectedTab); 

      return (
      <TabItem 
       key={panelId} 
       classname={classname} 
       idx={idx} 
       content={item} 
       onClick={this.tabChanged(idx, headline)} 
      /> 
     ); 
     }); 

     return tabs; 
     } 

     tabChanged(idx, headline) { 
     const { selectedTab } = this.props; 
     const { selectedFilter } = this.state; 
     const selectedFilterIdx = _.get(selectedFilter, 'idx', null); 
     if (selectedTab !== idx) { 
      this.props.resetNextPage(); 
      this.props.setTab(idx, selectedFilterIdx, headline); 
      this.closeDropdown(); 
     } 
     } 
    render() { 
    // const { panels, selectedTab } = this.props; 
    // if (!panels || panels.length === 0) return null; 
    // 
    // 
    // const { tabs, selectedTab } = this.props; 

    return (
     <div> 
     <ul>{this.state.tabs}</ul> 
     </div> 
    ); 
    } 
} 

export const TabItem = ({ classname, content, onClick, key }) => (
     <li key={key} className={`${classname} tab-item`} onClick={onClick} >{content}</li> 
    ); 

所以在的TabItemonClick={onClick}未定义为的onClick结束。

更多信息

这里是如何来工作,当这是在父容器的功能:

// renderDefaultTabs() { 
    // const { panels, selectedTab } = this.props; 
    // 
    // if (!panels || panels.length === 0) return; 
    // 
    // let filter = null; 
    // 
    // const tabs = panels.member.map((panel, idx) => { 
    //  const { id: panelId, headline } = panel; 
    //  const url = getHeaderLogo(panel, 50); 
    //  const item = url ? 
    //  <img src={url} alt={headline} /> : headline; 
    //  const classname = classNames([ 
    //  searchResultsTheme.tabItem, 
    //  (idx === selectedTab) ? searchResultsTheme.active : null, 
    //  ]); 
    // 
    //  filter = (idx === selectedTab) ? this.renderFilters(panel) : filter; 
    // 
    //  return (
    //  <li 
    //   key={panelId} 
    //   className={classname} 
    //   onClick={() => { 
    //   this.tabChanged(idx, headline); 
    //   }} 
    //  > 
    //   {item} 
    //  </li> 
    // ); 
    // }); 

所以我提取了这一点到SearchTabs包括移动tabChange d方法添加到我的新SearchTabs组件中。现在在集装箱上面,现在做这个的:

renderDefaultTabs() { 
    const { 
     onFilterClick, 
     panels, 
     resetNextPage, 
     selectedTab, 
     selectedFilter, 
     isDropdownOpen, 
    } = this.props; 

    return (<SearchTabs 
     panels={panels} 
     ... 
    />); 
    } 

注:renderDefaultTabs()在渲染被作为一个道具()容器和搜索调用它回来从而在搜索的使其呈现():

集装箱

render() { 
    return (
     <Search 
     request={{ 
      headers: searchHeaders, 
      route: searchRoute, 
     }} 
     renderTabs={this.renderDefaultTabs} 
     renderSearchResults={this.renderSearchResults} 
     handleInputChange={({ input }) => { 
      this.setState({ searchInput: input }); 
     }} 
     renderAltResults={true} 
     /> 
    ); 
    } 

搜索是一个共享组件,为应用程序使用。

更新

所以我提到,集装箱的render()传递renderDefaultTabs功能为道具,以<Search />。里面<Search />它最终做到这一点:render() { <div>{renderTabs({searchResults})}</div>}它调用容器的renderDefaultTabs功能,你可以在上面看到,最终呈现

Update

所以它是把它当作一个函数。当我点击的TabItem这只是奇怪,它不打我的tabChanged功能任何

更新

基督,它打我的tabChanged。错,我认为我很好。谢谢大家!

+0

的[ReactJS试图从的onClick函数中调用的setState和获取:现有状态转换误差过程中无法更新]可能的复制(https://stackoverflow.com/questions/44009524/reactjs -try-on-call-set-on-on-click-function-and-getting-can-update) –

+0

不是一个dup,我看着它,我做的是完全一样的东西,但我仍然无法工作。 – PositiveGuy

+0

'onClick = {this.tabChanged(idx,headline)}' –

回答

0

onClick={this.tabChanged(idx, headline)}

这不是传递给子组件的props功能的正确方法。不喜欢它(尽管不建议这样做)

onClick={() => this.tabChanged(idx, headline)}

UPDATE

我要添加更多的解释。通过onClick={this.tabChanged(idx, headline)},您正在执行tabChanged并将其返回值传递给onClick

与您以前的实现:onClick={() => { this.tabChanged(idx, headline); }},现在onClick将类似的功能:

onClick = {(function() { 
    this.tabChanged(idx, headline); 
})} 

所以它的工作原理与之前的实现。 随着你的新的实现,onClick={() => this.tabChanged(idx, headline)}应该工作

+0

为什么不推荐? – PositiveGuy

+0

箭头函数'()=>'将在每个'render'上创建一个全新的函数。你可以参考这里:https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md正确地做到这一点 –

+0

'onClick = {()=> this .tabChanged(idx,headline)}' - 这不起作用,我试过了,它仍然没有定义。 – PositiveGuy

相关问题