使用样式组件的React Native中的动态样式按钮
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>
预期结果
所以,我希望我的按钮看起来像这样...
实际结果
我所做的解决至今
当我使用巡视react-devtools,我可以看到outline
道具正在传递给Button
组件。
但道具不向下传递给它的任何儿童
的文档状态的Passed Props部分,“病急乱投医组件传递他们的所有道具”,但我想不是一路下跌?
我的问题
什么我需要改变,这样我可以动态风格的基础上它的道具我的按钮?
这里有:
const Button = (props) => {
return (
<ButtonContainer underlayColor={colors.highlight}>
<Label>
{props.children}
</Label>
</ButtonContainer>
);
};
如果ButtonContainer
是一个正常的阵营组成部分,你不会期望传递给Button
props
自动传递到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.Children
和React.cloneElement
的API可以传递下来,Label
。但ButtonContainer
由于显而易见的原因没有这样做,例如你不希望underlayColor
和onPress
自动传递到Label
。这会造成很多令人困惑的错误。
谢谢Satya!这一切都非常有意义。感谢您撰写了这样一个很好的解释,当然,它的工作原理与您描述的一样。 –
要添加到@ satya164的答案,你可以立即继承像这样的所有道具:''。这样你就不需要手动添加你想传递的每一个新的道具。 –