Welp
Welp

Reputation: 416

Re render Component when props updates (w/ Redux)

Ok so i have 2 components, Map and App. App component basically holds the map.

This is the code of my App:

import React, { Component } from 'react';
import { Text, View } from 'react-native';

import { StackNavigator, TabNavigator } from 'react-navigation';
//Redux
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

//Screen Imports
import CenterNew from './screens/CenterNew';
import Map from './components/Map';
import Profile from './containers/Profile';
import Review from './containers/Review';

import { connect } from 'react-redux';

var store = createStore(rootReducer, {}, applyMiddleware(thunk));

class App extends Component {
	
	render () {
		
		{ console.ignoredYellowBox = ['Remote debugger']; }

		const MainScreenNavigator = TabNavigator({
		  Centers: {screen: Map},
		  Review: {screen: Review},
		  Profile: {screen: Profile}
		});

		MainScreenNavigator.navigationOptions = {
		  title: this.props.map.title
		};

		const Screens = StackNavigator({
		  Home: {screen: MainScreenNavigator},
		  CenterNew: {screen: CenterNew}
		});


		return (
			<Provider store={store}>
	    	  <Screens />
	    	</Provider>
    	);
	}
}

const connectWithStore = (store, WrappedComponent, mapStateToProps) => {
  let ConnectedWrappedComponent = connect(mapStateToProps)(WrappedComponent);
  return (props) => {
    return <ConnectedWrappedComponent {...props} store={store} />
  }
}

const mapStateToProps = (state) => {
	return {
		map: state.map
	};
};

App = connectWithStore(createStore(rootReducer, {}, applyMiddleware(thunk)), App, mapStateToProps);

export default App;

In the snippet, i set the title using MainScreenNavigator.navigationOptions = { title: this.props.map.title };

So whenever App is rendered, I log the initial state as you could see in componentWillMount() and this is the result. A syou can see, the initial title is 'Home'

enter image description here

now, in my Map I have a button which triggers this action creator just to change the header text:

this.props.changeHeaderTitle('Test');
console.log(this.props.map);

code:

export const changeHeaderTitle = (title) => {
return {
    type: 'CHANGE_HEADER_TITLE',
    payload: title
};

};

and this is my reducer:

const INITIAL_STATE = {
	isPinnable: false,
	pinnedCoordinateLatitude: 0,
	pinnedCoordinateLongitude: 0,
	region: {
	    latitude: 14.582524,
	    longitude: 121.061547,
	    latitudeDelta: 0.007,
	    longitudeDelta: 0.007
	},
	title: '',
	searched: false
};

export default (state = INITIAL_STATE, action) => {
	switch(action.type) {
		case 'ENABLE_PINNING':
			return { ... state, isPinnable: true }
		case 'DISABLE_PINNING':
			return { ... state, isPinnable: false,
				pinnedCoordinateLatitude: action.payload.latitude,
				pinnedCoordinateLongitude: action.payload.longitude }
		case 'GET_PINNED_COORDINATE':
			let test = action.payload.longitude;

			return { 
				...state, 
				isPinnable: false,
				pinnedCoordinateLatitude: action.payload.latitude,
				pinnedCoordinateLongitude: action.payload.longitude
			}
		case 'GET_CURRENT_REGION':
			return { ...state, region: region }
		case 'CHANGE_CURRENT_REGION':
			return { ...state, region: action.payload}
		case 'CHANGE_HEADER_TITLE':
			return { ...state, title: action.payload }
		case 'SEARCHED_VIEW':
			return { ...state, searched: action.payload }
		default:
			return state;
	}
};

whenever the action is triggered, i know the title is updated because i log it as you can see in

this.props.changeHeaderTitle('Test');

console.log(this.props.map); enter image description here

but in my view, the title is still 'Home'.. I referred to this: rerender react component when prop changes and tried to use componentWillRecieveProps() but it is not logging when this.props.changeHeaderTitle('Test'); action is triggered from Map component.

Upvotes: 1

Views: 918

Answers (2)

Ansal Ali
Ansal Ali

Reputation: 1613

You can't update the screen title like in the code you provide.

 //This is only needed if you want to set the title from another screen

 static navigationOptions = ({ navigation }) => { 
const {state} = navigation;
 return { title: `${state.params.title}`, 
}; 
}; 
ChangeThisTitle = (titleText) => { 
const {setParams} = this.props.navigation; setParams({ title: titleText }) 
} 

//Your render method
render(){
//Views goes here
 }

To change the title you have call the change title method from the onPress.

You may please refer this link for more details.

Upvotes: 0

Tim
Tim

Reputation: 10719

You need to connect your Redux store with your component. Therefore you should add this snippet:

mapStateToProps(store){
    const { title } = store; 
    return { title }; 
}    
export default connect(mapStateToProps, { changeHeaderTitle })(App) 

The mapStateToProps function will subscribe to redux store updates. Every time your state changes, your component will rerender automatically. You can find more information about connecting components to the redux store here: react-redux api docs

Upvotes: 1

Related Questions