2017-08-05 51 views
1

我有一個React應用程序,其中包含選項卡和顯示的子項。如何將參數傳遞給React子的綁定函數?

<App> 
    <Nav> 
     <Tab1></Tab1> 
     <Tab2></Tab2> 
     <Tab3></Tab3> 
    </Nav> 
    <Section>Display Stuff Here</Section> 
    <Footer></Footer> 
</App> 

當我創造應用中的標籤,我有一個for循環,追加在地圖變量的標籤(這是應用程序的子陣營組件)。

for(...) { 
    tab = React.createElement(Tab, {changeDisplay:() => {this.handleClick(this.changeDisplay(i)}}); 
    myMap.set(i, tab); 
} 

它應該做的是傳遞從for循環遞增的i變量。我甚至做了一個console.log以確保它通過了1,2,3,4。然而,實際顯示的是最後一個變量:4.

在Tab類中,我有權訪問調用道具:

class Tab extends React.Component { 
    constructor(props) { 
     super(props); 
     this.tab = React.Component('div', null); 
    } 
    render() { 
     return this.tab; 
    } 
    componentDidMount() { 
     this.forceUpdate(); 
    } 
    componentWillUpdate(nextProps, nextState) { 
     this.tab = React.Component('div', {onClick: nextProps.changeDisplay}); 
    } 
} 

爲changeDisplay的值應該是唯一的每個標籤,以便TAB2應該只具有2的值,並且TAB3應該只有3等的for循環不應該是使下值添加到已經創建的任何以前的標籤,因爲它們已經制作並附加到地圖變量中。

有關如何使這項工作的任何建議?

我可以自定義函數:

changeDisplay1() { changeDisplay(1) }; 
changeDisplay2() { changeDisplay(2) }; 
changeDisplay3() { changeDisplay{3) }; 
changeDisplay4() { changeDisplay(4) }; 

不過,我想這樣做的正確的方式,而不是使得黑客。

+0

相關:https://stackoverflow.com/q/750486/5647260 – Li357

+0

任何你不以另一種方式去做的理由?還是你堅持讓它以這種方式工作? – Win

回答

0

React功能非常強大,您可以找到多種基於父狀態呈現組件列表的方法。這裏有一個我已經拉在一起的快速版本。

你可以在這裏查看工作副本:https://codesandbox.io/s/zzqLPrjO

說明:

我們創造可用,active tab,用於存儲數據,如標籤父組件。我們通過從Library對象上的鍵創建數組來加載可用的選項卡。 (這是完全可選的,但更容易添加額外的選項卡)

一旦選項卡加載到父組件中,我還創建了一個函數來設置/更改active tab。這將傳遞到我們的地圖中的標籤,該標籤呈現從Library對象中拾取的每個標籤。

在我們的Tab組件中,我們只是呈現名稱以及掛鉤到我們父組件的點擊事件,這會將active tab更改爲已被點擊的標籤。 (注意:請注意,我們如何避免渲染方法中的函數綁定,以便每次渲染組件時都不會創建新函數(這被認爲是不好的做法,這就是爲什麼我會避免這種做法。)

一旦活動標籤已經改變,我們做一個基本的查找到Library和渲染連接到該指數的成分

import React from 'react'; 
 
import { render } from 'react-dom'; 
 

 
// *--------------------- 
 
// | Tab Component 
 
// *--------------------- 
 

 
const activeTab = { 
 
    background: 'green', 
 
} 
 

 
class Tab extends React.Component { 
 
    change =() => this.props.change(this.props.name) 
 
    render =() => { 
 
    const { 
 
     name: NAME, 
 
     active: ACTIVE, 
 
    } = this.props; 
 
    const isActive = ACTIVE === NAME ? activeTab : null; 
 
    return <button style={isActive} onClick={this.change}>{this.props.name}</button> 
 
    } 
 
} 
 
    
 
// *--------------------- 
 
// | Mock list of Components 
 
// *--------------------- 
 
    
 
const Home =() => <div>Home</div> 
 
const About =() => <div>About</div> 
 

 
// *--------------------- 
 
// | Library of Components 
 
// *--------------------- 
 

 
const Library = { 
 
    Home, 
 
    About 
 
} 
 

 
// *--------------------- 
 
// | Display Components 
 
// *--------------------- 
 
    
 
const Display = ({screen}) => { 
 
    const Comp = Library[screen]; 
 
    return screen === null ? <div>Please select a tab</div> : <Comp/> 
 
} 
 

 
// *--------------------- 
 
// | Main App 
 
// *--------------------- 
 

 
class App extends React.Component { 
 
    state = { 
 
    tabs: [], 
 
    activeTab: null, 
 
    } 
 
    componentWillMount() { 
 
    const tabs = Object.keys(Library); 
 
    this.setState({ 
 
     tabs: tabs 
 
    }); 
 
    } 
 
    changeTab = (tab) => { 
 
    this.setState({ activeTab: tab }); 
 
    } 
 
    render() { 
 
    return (
 
     <div> 
 
     { this.state.tabs.map((tab,index) => { 
 
      return <Tab key={index} name={tab} active={this.state.activeTab} change={this.changeTab} /> 
 
     }) } 
 
     <Display screen={this.state.activeTab} /> 
 
     </div> 
 
    ) 
 
    } 
 
} 
 

 
render(<App />, document.getElementById('root'));

+0

我想給安德魯李最好的回答for循環修復,但這絕對引導我在概念上正確的方向(即這是一個艱難的決定)。我確實有更新Tabs的問題。我有一個CSS類,顯示一個標籤爲點擊/活動。因此,我可以顯示標籤2被點擊並且現在處於活動狀態,但它不會強制標籤1更新並將其自身與新的活動標籤(2)進行比較以重置爲非活動狀態。 – DeadSupra

+0

@DeadSupra該示例已更新爲活動標籤樣式。如果您將其從父狀態掛鉤,那麼當您更改活動選項卡時,它將重新呈現子組件。讓我知道你是否需要更多信息。 :) – Win

+0

完美。對我自己的代碼做了輕微的修改,但總體上讓我走上了正確的道路。非常感謝 – DeadSupra