React native 导航实验:如何根据导航卡内容更改导航标题

React native 导航实验:如何根据导航卡内容更改导航标题,react-native,React Native,有时,导航标题的标题将由导航卡的内容决定。例如,在What's应用程序中,当您在聊天窗口中时,您将看到用户名和照片 我想知道怎么做,因为NavigationHeader是NavigationCard的父级 <NavigationAnimatedView navigationState={navigationState} style={styles.container} onNavigate={(action)

有时,导航标题的标题将由导航卡的内容决定。例如,在What's应用程序中,当您在聊天窗口中时,您将看到用户名和照片

我想知道怎么做,因为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)}
        />
{
如果(action.type==='back'){
导航返回();
}
}}
RenderRoverLay={this.\u renderHeader.bind(this)}
renderScene={props=>(
)}
/>
这个._渲染图(路线)}
renderLeftComponent={()=>此。_renderHeaderLeft(路由)}
renderRightComponent={()=>this.\u renderHeaderRight(路由)}
/>

我尝试在NavigationCard上创建一个ref,这样我就可以调用包含信息的组件,但在renderTitleComponent方法中还不可用。

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

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'});
}
renderTitleComponent={(props) => {
  return <NavigationHeaderTitle>
    {props.scene.navigationState.title
  </NavigationHeaderTitle>;
}}
我不喜欢调用onNavigate,因为它显然与导航无关,但它非常简单,迄今为止运行良好


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

第一部分,在导航到该卡的
onNavigate
中,您应该在您的状态中传递一个标题,该标题将自动拉入并用于标题组件:

this.props.onNavigate({key:'NewView',title:myuser.Username})

第二部分,我看到您正在覆盖
renderitlecomponent
。这意味着您将负责自己传递标题(或您想要的任何其他数据)。幸运的是,通过执行以下操作,您仍然可以从场景的
导航状态
(与默认的
渲染器组件
代码中的方式相同)中读取它:

componentWillMount() {
    this.props.onNavigate({type: 'updateTitle', title: 'Foo'});
}
renderTitleComponent={(props) => {
  return <NavigationHeaderTitle>
    {props.scene.navigationState.title
  </NavigationHeaderTitle>;
}}
renderTitleComponent={(道具)=>{
返回
{props.scene.navigationState.title
;
}}

在这种情况下,您可能希望在
navigationState
对象中传入用户本身,这样您也可以抓取配置文件照片。

我对这个问题的解决方案非常简单,但我不确定它是否太粗糙。您需要更改的唯一一件事是缩小部分,因此您可以将更改保留在一个位置。我只是动态更改
title
从状态变为推送/
弹出
操作出现:

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
操作。您可以通过手动将
标题
设置为
初始状态
来执行此操作:

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

它可用于更改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,
  };
}