没有redux

时间:2017-11-20 18:18:29

标签: react-native react-navigation

我在我的React Native项目中使用React Navigation库,并努力了解如何使用它来处理状态。 在正常的React Native应用程序中,我可以在顶级组件中使用state,并通过props从子组件中弹出事件,但是使用React Navigation,我似乎无法将任何道具传递给用作Screens的组件。

阅读related GitHub issue之后,似乎库开发人员非常痴迷于强迫每个人都使用某种全局事件处理程序 - 我猜是还是还是mobx。

需要修改以下The handler

state。当我开始尝试在应用程序内移动状态时,我陷入困境,因为我无法弄清楚如何:

  1. 将处理程序传递给TaskForm组件。
  2. 如果作为App.js
  3. 的一部分呈现,则将状态作为props传递给TaskList

    请避免回复"只需使用redux"。我相信在这个例子中使用redux将是一个巨大的矫枉过正。

4 个答案:

答案 0 :(得分:3)

我使用react native并在我的应用程序中反应导航而没有redux,到目前为止它工作得很好。诀窍是将screenProps一直传递到线下。

例如,我有一个更多视图。我创建了一个基本的更多视图,在堆栈中有2个子视图:

class More extends Component {
    render() {
        return <something>
    }
}

class SubView1 extends Component {...}
class SubView2 extends Component {...}

然后我创建堆栈:

const MoreStack = StackNavigator({
More: {
    screen: More
}, 
SubView1: {
    screen: SubView1,
},
...
}, options);

然后我创建了一个我导出的包装类:

export default class MoreExport extends Component {
    static navigationOptions = {
        title: "More"
    }

    render() {
        return <MoreStack screenProps={this.props.screenProps} />;
    }
}

如果所有这些都在More.js中,我可以从More.js导入更多,并在其他任何地方使用它。

如果我然后将screenProps传递到我的根视图,然后为每个图层都有一个包装类,我可以将screenProps一直传递下来,所有视图都可以使用this.props.screenProps访问它们。

我在每个StackNavigator和TabNavigator周围使用上面的包装器,并且screenProps一直向下传递。

例如,在我的根类的render方法中,我可以这样做:

return <More screenProps={{prop1: something, prop2: somethingElse}} />

然后MoreStack中的More类和每个SubView都可以访问这些道具。

如果您想要更多说明,请随时告诉我们!

免责声明:我不知道这是否是正确或推荐的方式,但确实有效

答案 1 :(得分:0)

在受到steffeydev的启发之后,我更多地围绕反应社区问题,发现了一个使用函数的包装器的一个非常简单的例子。

令人惊讶simple solution我不知道为什么我之前没有想过它。 功能如下: const createComponent = (instance, props) => navProps => React.createElement(instance, Object.assign({}, props, navProps));

感谢您的灵感,并指向screenProps,这让我找到了解决方案。

答案 2 :(得分:0)

您可以像这样将参数设置为导航:

static navigationOptions = ({ navigation }) => {
    return {
        tabBarIcon: ({ tintColor, focused }) =>
            <View>
                <Icon name="bell-ring" size={24} color={focused ? 'green' : 'black'} />
                {(navigation.state.params.badgeCount && navigation.state.params.badgeCount > 0) ?
                    <Text>{navigation.state.params.badgeCount}</Text>
                    :
                    <View></View>
                }
            </View>
    }
}

并更改badgeCount by:

this.props.navigation.setParams({ badgeCount: 3 })

答案 3 :(得分:0)

我一直在同一个问题上苦苦挣扎,并尝试了其他一些答案,然后才发现React Navigation文档的以下部分:https://reactnavigation.org/docs/en/stack-navigator.html#params

基本上,Screen中的每个Stack都可以传递params,其中可以包含处理程序,然后各个屏幕都可以与应用程序状态进行交互。

然后,我的一般结构是创建一个带有状态和处理程序的App类,然后根据需要将处理程序传递到每个导航Screen中。我不确定我是否正确使用此模式,但这是我理解常规React教程的方式。

示例:在我的演示应用中,我的页面流如下:

  • 公园取景器屏幕->公园详细信息屏幕(执行Bookmark操作
  • 书签列表屏幕->公园详细信息屏幕

如果找到公园,则可以单击Bookmark按钮,该按钮会将公园添加到“书签”屏幕上显示的书签列表中。然后,您可以单击公园书签以查看详细信息。

我的App通常看起来像这样:

import React, { Component } from 'react';

// Screens
import ParkFinderScreen from './Components/ParkFinderScreen';
import ParkBookmarksScreen from './Components/ParkBookmarksScreen';
import ParkDetailsScreen from './Components/ParkDetailsScreen';

// Navigation
import { createStackNavigator, createBottomTabNavigator, createAppContainer } from 'react-navigation';

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      bookmarks: new Map()
    };
  }

  // Bookmark the park shown in the detail section.
  handleBookmark (park) {
    let newBookmarks = this.state.bookmarks;

    newBookmarks.set(park.parkCode, park);

    this.setState({
      bookmarks: newBookmarks
    });
  }

  render() {
    const FinderStack = createStackNavigator(
      {
        ParkFinder: {
          screen: ParkFinderScreen
        },
        ParkFinderDetails: {
          screen: ParkDetailsScreen,
          params: {
            handleBookmark: (park) => this.handleBookmark(park),
          }
        },
      }
    );

    const BookmarksStack = createStackNavigator(
      {
        ParkBookmarks: {
          screen: ParkBookmarksScreen,
          params: {
            bookmarks: this.state.bookmarks
          }
        },
        ParkBookmarksDetails: {
          screen: ParkDetailsScreen,
        },
      }
    );

    const AppNavigator = createBottomTabNavigator(
      {
        Bookmarks: BookmarksStack,
        Finder: FinderStack,
      }
    );

    const AppContainer = createAppContainer(AppNavigator);

    return (
      <AppContainer/>
    );
  }
}

export default App;

我正在使用Apollo Client,但已删除了那些部分。

Screen组件中,您可以使用props来访问this.props.navigation.getParam('bookmarks')

我遇到的一个问题是,每当我更改应用程序状态时,都会进入第一个屏幕。状态已更新,但有点令人迷惑。我不确定是否可以在停留在屏幕上的同时更新应用状态。我可以理解,鉴于应用程序状态已更新,所有子项都需要更新,因此当前屏幕(我认为是子项的一部分)被重置。我不知道这是系统的限制还是设计组件的副产品。

我希望这对某人有帮助。这似乎与React Native的预期行为保持一致。图书馆团队似乎真的希望您不要使用Redux。 https://reactnavigation.org/docs/en/redux-integration.html