2017-08-26 37 views
1

首先,我對React相當陌生,所以我仍然在學習我的方法。在React中使用情緒CSS-in-JS與主題

我在使用ThemesEmotion設置Introduction Article (Medium.com)。但我堅持試圖將內compose

例如使用一個const使用主題顏色,我有:

const types = { 
    primary: (props) => css`color: ${props.theme.blue}`, 
    secondary: (props) => css`color: ${props.theme.red}` 
}; 

const Button = withTheme(styled.button` 
    composes: ${props => types[props.type]}; 
`); 

(這是一個人爲的例子在現實中,我如果我渲染<Button type="primary">A Button</Button>,則顏色不會被應用。事實上,如果我檢查元素,我甚至不會看到color樣式。

但是,如果不是我改變Button到:

const Button = withTheme(styled.button` 
    composes: ${types.primary}; 
`); 

然後我看到應用了正確的顏色。

我不完全確定我在這裏做錯了什麼。

回答

2

只是一個小背景:

ES2015的Tagged template literals是模板文字由可以通過函數解析「標記」它與一個(如styled.button)。該函數接收模板文字和所有${}佔位符並返回結果字符串。 ${}可以包含任何被認爲是javascript表達式的內容,例如一個值,一個函數等等。

對於情感上的styled,如果你傳遞一個函數到任何佔位符中,它會調用該函數,傳入你已經使用的元素的道具(在您的示例a button)作爲第一個參數。如果使用withTheme調用將styled模板文字包裝起來,那麼該參數對象將包含您最初在應用的基本組件處提供給<ThemeProvider>的主題道具。

在你的例子中,它爲第二個代碼塊工作的原因是因爲你正在傳遞一個函數,它將返回一個值。在第一個代碼塊中,你傳遞一個被調用的函數將返回另一個函數。這意味着結果樣式將包含一個函數,而不是一個值。

const types = { 
    primary: (props) => css`color: ${props.theme.blue}`, 
    secondary: (props) => css`color: ${props.theme.red}` 
}; 

const Button = withTheme(styled.button` 
    composes: ${props => types[props.type]}; 
`); 

在「主要」上述評價了該情況:

const Button = withTheme(styled.button` 
    composes: ${props => (props) => css`color: ${props.theme.blue}`}; 
`); 

正如你看到的是一個級別太深。該主題將作爲props的一部分傳入,但需要調用第二個更深的函數來調用css函數。在第二個代碼塊中,「主要」將評估爲:

const Button = withTheme(styled.button` 
    composes: ${(props) => css`color: ${props.theme.blue}`}; 
`); 

這將給出正確的結果作爲styled.button將通過道具和css直接使用它們所調用的函數內。

希望這是有道理的。這是我的第一個堆棧溢出答案嘗試,所以如果可能的話,我很樂意改進它。