| 
									
										
										
										
											2018-10-12 15:37:13 -04:00
										 |  |  | --- | 
					
						
							|  |  |  | title: Extract Local State into Redux | 
					
						
							|  |  |  | --- | 
					
						
							|  |  |  | ## Extract Local State into Redux
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 01:50:30 +11:00
										 |  |  | ### Hint 1
 | 
					
						
							|  |  |  | You need to change the following sections: | 
					
						
							|  |  |  | * default state declarations: remove `messages` | 
					
						
							|  |  |  | * `submitMessage`: use `props` | 
					
						
							|  |  |  | * `render`: the unordered list should use `props` instead of `this.state.messages` | 
					
						
							| 
									
										
										
										
											2018-10-12 15:37:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 01:50:30 +11:00
										 |  |  | ### Hint 2
 | 
					
						
							|  |  |  | Replace `this.state.messages` with `this.props.messages`. | 
					
						
							| 
									
										
										
										
											2018-10-12 15:37:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 01:50:30 +11:00
										 |  |  | ### Hint 3
 | 
					
						
							|  |  |  | The `submitMessage` function still needs to set the state of the `input`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Solution
 | 
					
						
							|  |  |  | <details> | 
					
						
							|  |  |  |   <summary>Spoiler!</summary> | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | ```jsx | 
					
						
							|  |  |  | // Redux: | 
					
						
							|  |  |  | const ADD = 'ADD'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const addMessage = (message) => { | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     type: ADD, | 
					
						
							|  |  |  |     message: message | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const messageReducer = (state = [], action) => { | 
					
						
							|  |  |  |   switch (action.type) { | 
					
						
							|  |  |  |     case ADD: | 
					
						
							|  |  |  |       return [ | 
					
						
							|  |  |  |         ...state, | 
					
						
							|  |  |  |         action.message | 
					
						
							|  |  |  |       ]; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       return state; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const store = Redux.createStore(messageReducer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // React: | 
					
						
							|  |  |  | const Provider = ReactRedux.Provider; | 
					
						
							|  |  |  | const connect = ReactRedux.connect; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Change code below this line | 
					
						
							|  |  |  | class Presentational extends React.Component { | 
					
						
							|  |  |  |   constructor(props) { | 
					
						
							|  |  |  |     super(props); | 
					
						
							| 
									
										
										
										
											2019-03-29 16:20:11 +01:00
										 |  |  |      | 
					
						
							|  |  |  |     // Remove property 'messages' from Presentational's local state | 
					
						
							| 
									
										
										
										
											2019-03-30 01:50:30 +11:00
										 |  |  |     this.state = { | 
					
						
							|  |  |  |       input: '' | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     this.handleChange = this.handleChange.bind(this); | 
					
						
							|  |  |  |     this.submitMessage = this.submitMessage.bind(this); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   handleChange(event) { | 
					
						
							|  |  |  |     this.setState({ | 
					
						
							|  |  |  |       input: event.target.value | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   submitMessage() { | 
					
						
							| 
									
										
										
										
											2019-03-29 16:20:11 +01:00
										 |  |  |    | 
					
						
							|  |  |  |     // Call 'submitNewMessage', which has been mapped to Presentational's props, with a new message; | 
					
						
							|  |  |  |     // meanwhile, remove the 'messages' property from the object returned by this.setState(). | 
					
						
							|  |  |  |     this.props.submitNewMessage(this.state.input); | 
					
						
							|  |  |  |     this.setState({ | 
					
						
							|  |  |  |       input: '' | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2019-03-30 01:50:30 +11:00
										 |  |  |   } | 
					
						
							|  |  |  |   render() { | 
					
						
							|  |  |  |     return ( | 
					
						
							|  |  |  |       <div> | 
					
						
							|  |  |  |         <h2>Type in a new Message:</h2> | 
					
						
							|  |  |  |         <input | 
					
						
							|  |  |  |           value={this.state.input} | 
					
						
							|  |  |  |           onChange={this.handleChange}/><br/> | 
					
						
							|  |  |  |         <button onClick={this.submitMessage}>Submit</button> | 
					
						
							|  |  |  |         <ul> | 
					
						
							| 
									
										
										
										
											2019-03-29 16:20:11 +01:00
										 |  |  |            {/* The messages state is mapped to Presentational's props; therefore, when rendering, | 
					
						
							|  |  |  |                you should access the messages state through props, instead of Presentational's | 
					
						
							|  |  |  |                local state. */} | 
					
						
							| 
									
										
										
										
											2019-03-30 01:50:30 +11:00
										 |  |  |           {this.props.messages.map( (message, idx) => { | 
					
						
							|  |  |  |               return ( | 
					
						
							|  |  |  |                  <li key={idx}>{message}</li> | 
					
						
							|  |  |  |               ) | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         </ul> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | // Change code above this line | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const mapStateToProps = (state) => { | 
					
						
							|  |  |  |   return {messages: state} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const mapDispatchToProps = (dispatch) => { | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     submitNewMessage: (message) => { | 
					
						
							|  |  |  |       dispatch(addMessage(message)) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const Container = connect(mapStateToProps, mapDispatchToProps)(Presentational); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AppWrapper extends React.Component { | 
					
						
							|  |  |  |   render() { | 
					
						
							|  |  |  |     return ( | 
					
						
							|  |  |  |       <Provider store={store}> | 
					
						
							|  |  |  |         <Container/> | 
					
						
							|  |  |  |       </Provider> | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  |   ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> |