2017-08-25 70 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

相關問題