Button组件通常由Text元素组成,该元素用TouchableHighlight(或其他touchable)包装。我正在尝试创建一个使用styled-components样式的按钮组件,但是我的样式很难动态响应道具。
下面,我创建了一个按钮组件,类似于样式化组件文档中的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>
所以,我希望我的纽扣看起来像这样...
当我使用react-devtools进行检查时,我可以看到outling
道具正在向下传递到button
组件。
但这个道具不会传给它的任何一个孩子
文档的pass Props部分表示,“styled-components pass on all ther Props”,但我猜不是一直往下走?
我需要更改什么,以便我可以根据按钮的道具动态地设置按钮的样式?
这里有:
const Button = (props) => {
return (
<ButtonContainer underlayColor={colors.highlight}>
<Label>
{props.children}
</Label>
</ButtonContainer>
);
};
如果ButtonContainer
是一个普通的React组件,则您不会期望传递给Button
的Props
会自动传递给ButtonContainer
。您必须执行
来执行此操作。
实际上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>
);
};
从技术上讲,React组件可以向下传递道具给它的子组件,因此ButtonContainer
可以使用React.Childre
和React.CloneElement
API向下传递道具给Label
。但是buttoncontainer
由于明显的原因不会这样做,例如,您不希望underlayColor
和onpress
自动传递给label
。它会引起很多混乱的虫子。