2016-12-28 122 views
1

我試圖將無狀態組件添加到我的按鈕。如何將無狀態組件添加到可觸摸組件

const button = ({onButtonPress, buttonText}) => { 
return (
    <TouchableHighlight 
    onPress={() => onButtonPress()}> 
    <ButtonContent text={buttonText}/> 
    </TouchableHighlight> 
) 
}; 

,並得到這個錯誤:

Warning: Stateless function components cannot be given refs (See ref "childRef" 
in StatelessComponent created by TouchableHighlight). 
Attempts to access this ref will fail. 

我讀到了關於這個問題,但我還是新的JavaScript和RN,並沒有找到一個解決辦法。任何幫助,將不勝感激。

全碼:

GlossaryButtonContent:

import React from 'react'; 
import { 
    View, 
    Text, 
    Image, 
    StyleSheet 
} from 'react-native'; 
import Colours from '../constants/Colours'; 
import { 
    arrowForwardDark, 
    starDarkFill 
} from '../assets/icons'; 

type Props = { 
    text: string, 
    showFavButton?: boolean 
} 

export default ({text, showFavButton} : Props) => { 
    return (
    <View style={styles.container}> 
     {showFavButton && 
     <Image 
     style={styles.star} 
     source={starDarkFill}/>} 

     <Text style={[styles.text, showFavButton && styles.favButton]}> 
     {showFavButton ? 'Favourites' : text} 
     </Text> 

     <Image 
     style={styles.image} 
     source={arrowForwardDark} 
     opacity={showFavButton ? .5 : 1}/> 
    </View> 
); 
}; 

const styles = StyleSheet.create({ 
    container: { 
    flex: 1, 
    flexDirection: 'row', 
    alignItems: 'center' 
    }, 

    favButton: { 
    marginLeft: 10, 
    color: Colours.darkTextHalf 
    }, 

    text: { 
    flex: 1, 
    paddingTop: 5, 
    marginLeft: 20, 
    fontFamily: 'Bariol-Bold', 
    fontSize: 24, 
    color: Colours.darkText 
    }, 

    image: { 
    marginRight: 20 
    }, 

    star: { 
    marginLeft: 10 
    } 
}); 

GlossaryButton:

import React from 'react'; 
import { 
    TouchableHighlight, 
    StyleSheet 
} from 'react-native'; 
import Colours from '../constants/Colours'; 
import ShadowedBox from './ShadowedBox'; 
import GlossaryButtonContent from './GlossaryButtonContent'; 

type Props = { 
    buttonText: string, 
    onButtonPress: Function, 
    rowID: number, 
    sectionID?: string, 
    showFavButton?: boolean 
} 

export default ({buttonText, onButtonPress, rowID, sectionID, showFavButton} : Props) => { 
    return (
    <ShadowedBox 
     style={styles.container} 
     backColor={showFavButton && Colours.yellow}> 
     <TouchableHighlight 
     style={styles.button} 
     underlayColor={Colours.green} 
     onPress={() => onButtonPress(rowID, sectionID)}> 
     <GlossaryButtonContent 
      text={buttonText} 
      showFavButton={showFavButton}/> 
     </TouchableHighlight> 
    </ShadowedBox> 
); 
}; 

const styles = StyleSheet.create({ 
    container: { 
    flex: 1, 
    height: 60, 
    marginBottom: 10, 
    borderRadius: 5 
    }, 

    button: { 
    flex: 1, 
    borderRadius: 5 
    } 
}); 
+1

你可以發佈ButtonContent'的'代碼? –

回答

1

基本上無狀態組件不能有參考文獻。

因此,在渲染樹中間有一個無狀態的組件會在ref鏈中創建一個void,這意味着你不能訪問下面的組件。

那麼,問題來源於試圖做到這一點:

let Stateless = (props) => (
    <div /> 
); 
let Wrapper = React.createClass({ 
    render() { 
    return <Stateless ref="stateeee" /> 
    } 
}); 

TouchableHighlightneeds to give a ref to its child。這觸發了這個警告。

你不能真正做一個無狀態組件的TouchableHighlight

解決孩子:

使用createClassclass創造TouchableHighlight孩子,也就是GlossaryButtonContent

this github issue for more infothis one

+0

謝謝。不知道這是否是好的做法,但最終只把它們放在同一個文件中: 'const button =({onButtonPress,buttonText})=> {const renderButtonContent =()=> {return(...); };返回( onButtonPress()}> {renderButtonContent()}); }' – Lance

+0

@Lance這看起來不太可讀。爲什麼不把它們作爲單獨的組件使用'React.createClass'?它不是強制使用無狀態組件。除了減少混亂(如果使用上面的代碼,你將失去一個好處),它們不會增加任何好處。 –

+0

對不起,我嘗試過,但不知道如何在評論中格式化代碼。我認爲React.createClass正在獲得折舊,以支持擴展React.Component。如果無狀態組件沒有增加任何好處,那麼爲什麼使用它們呢?只能減少1行代碼? – Lance