导航实验:如何根据NavigationCard内容更改导航标题

时间:2016-05-03 12:02:16

标签: react-native

有时,导航标题的标题将由NavigationCard的内容决定。例如。在什么是应用程序中,当您进入聊天窗口时,您将看到用户名和照片。

我想知道如何做到这一点,因为NavigationHeader是NavigationCard的父级。

    <NavigationAnimatedView
            navigationState={navigationState}
            style={styles.container}
            onNavigate={(action) => {
                if (action.type === 'back') {
                    navigateBack();
                }
            }}
            renderOverlay={this._renderHeader.bind(this)}
            renderScene={props => (
                <NavigationCard
                    {...props}
                    key={props.scene.navigationState.key}
                    ref="sceneRef"
                    renderScene={this._renderScene.bind(this)}
                />
            )}
        />

    <NavigationHeader
            {...props}
            navigationState = {navigationState}
            viewProps={props}
            style={[styles.appbar]}
            renderTitleComponent={() => this._renderTitle(route)}
            renderLeftComponent={() => this._renderHeaderLeft(route)}
            renderRightComponent={() => this._renderHeaderRight(route)}
        />

我尝试在NavigationCard上创建一个ref,所以我可以调用包含信息的组件,但是在renderTitleComponent方法中还没有。

4 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。据我所知,没有最佳做法可以在任何地方记录。我添加了一个自定义导航缩减器,用于设置当前场景的标题。

function CustomReducer(lastState, action) {
    switch (action.type) {
        case 'updateTitle':
            let newState = {...lastState, children: lastState.children.slice()};
            newState.children[lastState.children.length - 1].title = action.title;
            return newState;

    }
    return lastState;
}

现在你可以做这样的事情:

componentWillMount() {
    this.props.onNavigate({type: 'updateTitle', title: 'Foo'});
}

我不喜欢在导航上寻找明显不与导航相关的东西,但它非常简单并且到目前为止效果很好。

我也希望看到其他一些方法。

答案 1 :(得分:1)

第一部分是在导航到该卡的onNavigate中,您应该在您的州内传递一个标题,该标题会被自动拉出并用于标题组件: this.props.onNavigate({key: 'NewView', title: myuser.Username})}

第二部分,我看到你压倒renderTitleComponent。这意味着您将负责自己传递标题(或您想要的任何其他数据)。幸运的是,您仍然可以通过以下方式从场景中navigationState(与默认的renderTitleComponent代码相同的方式)阅读它:

renderTitleComponent={(props) => {
  return <NavigationHeaderTitle>
    {props.scene.navigationState.title
  </NavigationHeaderTitle>;
}}

在这种情况下,您可能希望在navigationState对象中传递用户本身,因此您也可以抓取个人资料照片。

答案 2 :(得分:1)

我对这个问题的解决方案非常简单,但我不确定它是不是太过于hacky。您需要更改的只是减速器部件,因此您可以在一个地方保持更改。我只是在title / PUSH操作出现时动态更改POP状态:

const initialState = {
    index: 0,
    routes: [
        {key: 'cities', title: 'Cities'},
    ],
};

export const reducer = (state = initialState, action) => {
    switch (action.type) {
        case '@@redux/INIT': {
            return {...state, title: state.routes[0].title};
        }
        case actionTypes.PUSH: {
            // some additional logic
            const newState = {...state, title: action.newState.title};
            return NavigationStateUtils.push(newState, action.newState);
        }
        case actionTypes.POP: {
            // some additional logic
            const newState = {...state, title: state.routes[state.index - 1].title};
            return NavigationStateUtils.pop(newState);
        }
    }
    return state;
};

请注意,我正在聆听@@redux/INIT行动。您可以通过手动将title设置为initialState

来省略此操作
const initialState = {
    index: 0,
    routes: [
        {key: 'cities', title: 'Cities'},
    ],
};

答案 3 :(得分:0)

它可以在reducer中更改标题。请记住,routes.slice()不会克隆数组中的对象。以下功能适用于标准标题逻辑等

  case t.CHANGE_ROUTE_TITLE:{

  let routes = state.routes.slice()
  let i = routes.length - 1
  routes[i] = {
    ...routes[i],
    title: action.payload,
    searchPlaceholder: 'Zoek in ' + action.payload
  }

  return {
    ...state,
    index: routes.length - 1,
    routes,
  };
}