反应导航:根据 redux store 更改 tabNavigator 样式
react navigation: change tabNavigator style based on redux store
所以我尝试根据商店状态设置 tabNavigator 的样式:
import React from 'react';
import { connect } from 'react-redux';
import { TabNavigator } from 'react-navigation';
const Tabs = TabNavigator(
// Screens
{
Boards: {
screen: Boards,
navigationOptions: {
tabBarLabel: 'Boards',
tabBarIcon: () => <MaterialCommunityIcon name="bulletin-board" size={25} color="white" />,
},
},
Bookmarks: {
screen: Bookmarks,
navigationOptions: {
tabBarLabel: 'Bookmarks',
tabBarIcon: () => <EntypoIcon name="bookmarks" size={25} color="white" />,
},
},
Settings: {
screen: Settings,
navigationOptions: {
tabBarLabel: 'Settings',
tabBarIcon: () => <MaterialCommunityIcon name="settings" size={25} color="white" />,
},
},
},
// TabNavigator configuration
{
tabBarPosition: 'bottom',
tabBarOptions: {
showIcon: true,
showLabel: false,
renderIndicator: () => null,
style: {
// TODO: Make tabNavigation color change based on current selected theme.
backgroundColor: this.props.theme === 'default' ? 'black' : 'red',
},
},
},
);
const mapStateToProps = state => {
return {
theme: state.configuration.theme,
};
};
export default connect(mapStateToProps)(Tabs);
但是当我尝试使用 this.props.theme 我得到: undefined is not an object (evaluating 'this.props.theme')
我想这是因为 tabNavigator 不接受道具或类似的东西,所以我无法将 tabNavigator 连接到 redux商店,那么我该如何实现我想要做的事情呢?
编辑 1
尝试按照上面建议的方式使用自定义标签栏解决此问题后,弹出此错误:
代码:
TabBar.js
import React from 'react';
import { connect } from 'react-redux';
import { TabBarBottom } from 'react-navigation';
const TabBar = ({ theme }) => (
<TabBarBottom style={{ backgroundColor: theme === 'dark' ? 'black' : 'red' }} />
);
const mapStateToProps = state => ({
theme: state.configuration.theme,
});
export default connect(mapStateToProps)(TabBar);
router.js
import { TabNavigator } from 'react-navigation';
import TabBar from './components/TabBar';
import Boards from './screens/Boards';
import Settings from './screens/Settings';
import Bookmarks from './screens/Bookmarks';
const Tabs = TabNavigator(
// Screens
{
Boards: {
screen: Boards,
navigationOptions: {
tabBarLabel: 'Boards',
tabBarIcon: () => <MaterialCommunityIcon name="bulletin-board" size={25} color="white" />,
},
},
Bookmarks: {
screen: Bookmarks,
navigationOptions: {
tabBarLabel: 'Bookmarks',
tabBarIcon: () => <EntypoIcon name="bookmarks" size={25} color="white" />,
},
},
Settings: {
screen: Settings,
navigationOptions: {
tabBarLabel: 'Settings',
tabBarIcon: () => <MaterialCommunityIcon name="settings" size={25} color="white" />,
},
},
},
// TabNavigator configuration
{
tabBarPosition: 'bottom',
tabBarComponent: TabBar,
},
);
export default Tabs;
您可以创建自己的标签栏,将其连接到导航器和 redux。
const MyAwesomeTabBar = ({theme}) => (
<View>
...
</View>
)
export default connect(mapStateToProps)(MyAwesomeTabBar);
然后在您的导航器定义中:
const Tabs = TabNavigator(
// Screens
{
...
},
// TabNavigator configuration
{
tabBarPosition: 'bottom',
tabBarComponent: MyConnectedAwesomeTabBar
},
);
至于 presentational/functional 组件的分离 - 我认为与其说不这样做是不好的做法,不如说这样做是好的做法。而且,您也可以很容易地在这里将它分开,只需将 MyAwesomeTabBar
作为您的功能组件,它使用了一堆表示性组件。
所以我尝试根据商店状态设置 tabNavigator 的样式:
import React from 'react';
import { connect } from 'react-redux';
import { TabNavigator } from 'react-navigation';
const Tabs = TabNavigator(
// Screens
{
Boards: {
screen: Boards,
navigationOptions: {
tabBarLabel: 'Boards',
tabBarIcon: () => <MaterialCommunityIcon name="bulletin-board" size={25} color="white" />,
},
},
Bookmarks: {
screen: Bookmarks,
navigationOptions: {
tabBarLabel: 'Bookmarks',
tabBarIcon: () => <EntypoIcon name="bookmarks" size={25} color="white" />,
},
},
Settings: {
screen: Settings,
navigationOptions: {
tabBarLabel: 'Settings',
tabBarIcon: () => <MaterialCommunityIcon name="settings" size={25} color="white" />,
},
},
},
// TabNavigator configuration
{
tabBarPosition: 'bottom',
tabBarOptions: {
showIcon: true,
showLabel: false,
renderIndicator: () => null,
style: {
// TODO: Make tabNavigation color change based on current selected theme.
backgroundColor: this.props.theme === 'default' ? 'black' : 'red',
},
},
},
);
const mapStateToProps = state => {
return {
theme: state.configuration.theme,
};
};
export default connect(mapStateToProps)(Tabs);
但是当我尝试使用 this.props.theme 我得到: undefined is not an object (evaluating 'this.props.theme')
我想这是因为 tabNavigator 不接受道具或类似的东西,所以我无法将 tabNavigator 连接到 redux商店,那么我该如何实现我想要做的事情呢?
编辑 1
尝试按照上面建议的方式使用自定义标签栏解决此问题后,弹出此错误:
代码:
TabBar.js
import React from 'react';
import { connect } from 'react-redux';
import { TabBarBottom } from 'react-navigation';
const TabBar = ({ theme }) => (
<TabBarBottom style={{ backgroundColor: theme === 'dark' ? 'black' : 'red' }} />
);
const mapStateToProps = state => ({
theme: state.configuration.theme,
});
export default connect(mapStateToProps)(TabBar);
router.js
import { TabNavigator } from 'react-navigation';
import TabBar from './components/TabBar';
import Boards from './screens/Boards';
import Settings from './screens/Settings';
import Bookmarks from './screens/Bookmarks';
const Tabs = TabNavigator(
// Screens
{
Boards: {
screen: Boards,
navigationOptions: {
tabBarLabel: 'Boards',
tabBarIcon: () => <MaterialCommunityIcon name="bulletin-board" size={25} color="white" />,
},
},
Bookmarks: {
screen: Bookmarks,
navigationOptions: {
tabBarLabel: 'Bookmarks',
tabBarIcon: () => <EntypoIcon name="bookmarks" size={25} color="white" />,
},
},
Settings: {
screen: Settings,
navigationOptions: {
tabBarLabel: 'Settings',
tabBarIcon: () => <MaterialCommunityIcon name="settings" size={25} color="white" />,
},
},
},
// TabNavigator configuration
{
tabBarPosition: 'bottom',
tabBarComponent: TabBar,
},
);
export default Tabs;
您可以创建自己的标签栏,将其连接到导航器和 redux。
const MyAwesomeTabBar = ({theme}) => (
<View>
...
</View>
)
export default connect(mapStateToProps)(MyAwesomeTabBar);
然后在您的导航器定义中:
const Tabs = TabNavigator(
// Screens
{
...
},
// TabNavigator configuration
{
tabBarPosition: 'bottom',
tabBarComponent: MyConnectedAwesomeTabBar
},
);
至于 presentational/functional 组件的分离 - 我认为与其说不这样做是不好的做法,不如说这样做是好的做法。而且,您也可以很容易地在这里将它分开,只需将 MyAwesomeTabBar
作为您的功能组件,它使用了一堆表示性组件。