2016-12-28 121 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