2016-12-28 3 views
1

Я пытаюсь добавить элемент без состояния для моей кнопки.Как добавить компонент stateless к сенсорному компоненту

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. 

Я прочитал на вопросе, но я еще новичок в яваскрипт и 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

В основном, Апатриды компоненты не могут иметь рефов.

Итак, наличие компонента без гражданства в середине дерева рендеринга создаст пустоту в цепочке ссылок, то есть вы не сможете получить доступ к нижним компонентам.

Итак, проблема возникает от того, чтобы сделать это:

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

TouchableHighlightneeds to give a ref to its child. И это вызывает это предупреждение.

Ответ:

Вы не можете реально сделать без гражданства компонент ребенок TouchableHighlight

Решение:

Использование createClass или class создать ребенка TouchableHighlight, то есть GlossaryButtonContent.

См this github issue for more info и this one

+0

спасибо. Не уверен, что это хорошая практика, но закончил тем, что просто поместил их в один файл: 'const button = ({onButtonPress, buttonText}) => {const renderButtonContent =() => {return (...); }; return ( onButtonPress()}> {renderButtonContent()}); } ' – Lance

+0

@Lance Это не выглядит очень читаемым. Почему бы не оставить их в качестве отдельных компонентов и использовать 'React.createClass'? Не обязательно использовать компоненты без состояния. И они еще не добавляют никаких преимуществ *, кроме уменьшения беспорядка (преимущество, которое вы потеряете, если используете код выше). –

+0

Жаль, что я пробовал, но не знаю, как форматировать код в комментарии. Я думал, что React.createClass получает амортизацию в пользу расширений React.Component. Если компоненты без гражданства не добавляют никаких преимуществ, то зачем их использовать? Только для уменьшения кода на 1 строку? – Lance

Смежные вопросы