2017-11-04 112 views
2

Button組件一般由包含TouchableHighlight(或其他可觸摸的)的Text元素組成。我正在嘗試使用樣式組件創建一個Button組件樣式,但是難以讓我的樣式動態地響應道具。使用樣式組件的React Native中的動態樣式按鈕

按鈕組件

下面,我創建了一個Button組件類似的風格分量文檔中發現的Adapting based on props例子。

import React from 'react'; 
import { Text, TouchableHighlight } from 'react-native'; 
import styled from 'styled-components/native'; 

const colors = { 
    accent: '#911', 
    highlight: '#D22', 
    contrast: '#FFF', 
} 

const Label = styled.Text` 
    color: ${props => !props.outline ? colors.contrast : colors.accent}; 
    font-weight: 700; 
    align-self: center; 
    padding: 10px; 
` 

const ButtonContainer = styled.TouchableHighlight` 
    background-color: ${props => props.outline ? colors.contrast : colors.accent}; 
    width: 80%; 
    margin-top: 5px; 
    border-color: ${colors.accent}; 
    border-width: 2px; 
` 

const Button = (props) => { 
    return (
     <ButtonContainer 
      onPress={props.onPress} 
      underlayColor={colors.highlight} 
     > 
      <Label> 
       {props.children} 
      </Label> 
     </ButtonContainer> 
    ); 
}; 

export default Button; 

鍵用途

導入它,我用這樣的按鈕後...

<Button 
     outline 
     onPress={() => console.log('pressed')}> 
     Press Me! 
    </Button> 

預期結果

所以,我希望我的按鈕看起來像這樣...

enter image description here

實際結果

但相反,它看起來像這樣... enter image description here

我所做的解決至今

當我使用巡視react-devtools,我可以看到outline道具正在傳遞給Button組件。

enter image description here

但道具不向下傳遞給它的任何兒童

enter image description here

的文檔狀態的Passed Props部分,「病急亂投醫組件傳遞他們的所有道具」,但我想不是一路下跌?

我的問題

什麼我需要改變,這樣我可以動態風格的基礎上它的道具我的按鈕?

回答

5

這裏有:

const Button = (props) => { 
    return (
     <ButtonContainer underlayColor={colors.highlight}> 
      <Label> 
       {props.children} 
      </Label> 
     </ButtonContainer> 
    ); 
}; 

如果ButtonContainer是一個正常的陣營組成部分,你不會期望傳遞給Buttonprops自動傳遞到ButtonContainer。你必須做<ButtonContainer underlayColor={colors.highlight} {...props} />來做到這一點。

實際上ButtonContainer是一個正常的React組件,唯一的區別是你使用HOC預先應用了一些樣式。

此外,如果您將此問題解析爲React.createElement調用,您可以看到無法自動傳遞props,因爲函數的參數不會自動傳遞到其中的函數調用。

const Button = (props) => { 
    return React.createElement(ButtonContainer, { underlayColor: colors.highlight }, ...); 
}; 

它沒什麼特別的styled-components。你只需要將自己的道具傳遞給ButtonContainer以及Label

所以,你會你的代碼改寫爲:

const Button = (props) => { 
    return (
     <ButtonContainer underlayColor={colors.highlight} onPress={props.onPress} outline={props.outline}> 
      <Label outline={props.outline}> 
       {props.children} 
      </Label> 
     </ButtonContainer> 
    ); 
}; 

技術上一個陣營組件可以傳下去道具到它的孩子,所以ButtonContainer使用React.ChildrenReact.cloneElement的API可以傳遞下來,Label。但ButtonContainer由於顯而易見的原因沒有這樣做,例如你不希望underlayColoronPress自動傳遞到Label。這會造成很多令人困惑的錯誤。

+0

謝謝Satya!這一切都非常有意義。感謝您撰寫了這樣一個很好的解釋,當然,它的工作原理與您描述的一樣。 –

+0

要添加到@ satya164的答案,你可以立即繼承像這樣的所有道具:''。這樣你就不需要手動添加你想傳遞的每一個新的道具。 –