问题
I'm using react-navigation and have a StackNavigator with a ParentScreen and a ChildScreen.
Both screens have the same navigation bar with a dynamic value from redux. Implemented like described in Issue #313
This works as expected. When I'm in DetailScreen and I update the value for the count variable, it also updates the value in the navigation bar.
Problem is, if I go back to the parent scene, there is still the old value in the navigation bar. It doesn't update to the current value in redux store.
Child

Parent (when I go back)

ChildScreen
class ChildScreen extends Component {
static navigationOptions = {
title: ({ state }) => `Total: ${state.params && state.params.count ? state.params.count : ''}`
};
componentWillReceiveProps(nextProps) {
if (nextProps.count != this.props.count) {
this.props.navigation.setParams({ count: nextProps.count });
}
}
render() {
return (
<View>
<Button onPress={() => this.props.increment()} title="Increment" />
</View>
);
}
}
ParentScreen
class ParentScreen extends Component {
static navigationOptions = {
title: ({ state }) => `Total: ${state.params && state.params.count ? state.params.count : ''}`
};
}
Any advice?
回答1:
My advice:
Make sure that
ParentScreen
is connected through react-reduxconnect
function.If you want the title of
ParentScreen
to get updated automatically when the state of the store changes, connecting it won't be enough. You will have to use thecomponentWillReceiveProps
like you are doing in theChildScreen
Component.
Bonus: you could create a Higher Order Component for encapsulating that behaviour, like this:
const withTotalTitle = Component => props => {
class TotalTitle extends Component {
static navigationOptions = {
title: ({ state }) => `Total: ${state.params && state.params.count ? state.params.count : ''}`
};
componentWillReceiveProps(nextProps) {
if (nextProps.count != this.props.count) {
this.props.navigation.setParams({ count: nextProps.count });
}
}
render() {
return (
<Component {...props}/>
);
}
}
return connect(state => { count: state.total })(TotalTitle); // update this (I have no idea what the structure your state looks like)
};
And then you could use it like this:
const ChildScreen = withTotalTitle(({ increment }) => (
<View>
<Button onPress={() => increment()} title="Increment" />
</View>
));
const ParentScreen = withTotalTitle(() => (
<View>
<Text>Whatever ParentScreen is supposed to render.</Text>
</View>
));
回答2:
OP, this is likely to be a problem with your redux implementation. Are you familiar with how redux implements its store? I see no mention here which means it is likely that your increment function is merely updating the child component's state instead of dispatching actions and reducers. Please have a look at a proper redux implementation like this one: https://onsen.io/blog/react-state-management-redux-store/
回答3:
Have a common reducer for both parent and child. That way all the components(parent and child in your case) will get notified when the state changes.
Write a connect function for both parent and child. You'll receive the updated state in componentWillReceiveProps method. Use it as you please.
Hope it will help.
回答4:
You need to use props in order to pass the incremented value from child to parent component.
find the article below. It has a great example of communications between parent and child components.
http://andrewhfarmer.com/component-communication/
Thanks
来源:https://stackoverflow.com/questions/43347536/react-navigation-how-to-update-navigation-title-for-parent-when-value-comes-fr