--- id: 5a24c314108439a4d4036148 title: Connettere Redux all'app Messaggi challengeType: 6 forumTopicId: 301427 dashedName: connect-redux-to-the-messages-app --- # --description-- Ora che sai come usare `connect` per connettere React a Redux, puoi applicare quello che hai imparato al tuo componente React che gestisce i messaggi. Nell'ultima lezione, il componente che hai collegato a Redux è stato chiamato `Presentational`, e questo non è stato arbitrario. Questo termine *generalmente* si riferisce a componenti React che non sono direttamente collegati a Redux. Sono semplicemente responsabili della presentazione dell'interfaccia utente e fanno questo in funzione delle props che ricevono. Al contrario, i componenti contenitore sono collegati a Redux. Essi sono tipicamente responsabili della spedizione delle azioni allo store e spesso passano lo stato dello store ai componenti figli come props. # --instructions-- L'editor di codice contiene tutto il codice che hai scritto finora in questa sezione. L'unico cambiamento è che il componente React è stato rinominato in `Presentational`. Crea un nuovo componente memorizzato in una costante chiamata `Container` che utilizza `connect` per collegare il componente `Presentational` a Redux. Poi, in `AppWrapper`, presenta il componente React Redux `Provider`. Passa a `Provider` lo `store` di Redux come una prop e presenta `Container` come figlio. Una volta che sarà tutto configurato, vedrai nuovamente l'app dei messaggi presentata nella pagina. # --hints-- L' `AppWrapper` dovrebbe essere presentata nella pagina. ```js assert( (function () { const mockedComponent = Enzyme.mount(React.createElement(AppWrapper)); return mockedComponent.find('AppWrapper').length === 1; })() ); ``` Il componente `Presentational` dovrebbe essere presentato nella pagina. ```js assert( (function () { const mockedComponent = Enzyme.mount(React.createElement(AppWrapper)); return mockedComponent.find('Presentational').length === 1; })() ); ``` Il componente `Presentational` dovrebbe fare il render degli elementi `h2`, `input`, `button`e `ul`. ```js assert( (function () { const mockedComponent = Enzyme.mount(React.createElement(AppWrapper)); const PresentationalComponent = mockedComponent.find('Presentational'); return ( PresentationalComponent.find('div').length === 1 && PresentationalComponent.find('h2').length === 1 && PresentationalComponent.find('button').length === 1 && PresentationalComponent.find('ul').length === 1 ); })() ); ``` Il componente `Presentational` dovrebbe ricevere `messages` dallo store Redux come prop. ```js assert( (function () { const mockedComponent = Enzyme.mount(React.createElement(AppWrapper)); const PresentationalComponent = mockedComponent.find('Presentational'); const props = PresentationalComponent.props(); return Array.isArray(props.messages); })() ); ``` Il componente `Presentational` dovrebbe ricevere il creatore dell'azione `submitMessage` come prop. ```js assert( (function () { const mockedComponent = Enzyme.mount(React.createElement(AppWrapper)); const PresentationalComponent = mockedComponent.find('Presentational'); const props = PresentationalComponent.props(); return typeof props.submitNewMessage === 'function'; })() ); ``` # --seed-- ## --after-user-code-- ```jsx ReactDOM.render(, document.getElementById('root')) ``` ## --seed-contents-- ```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: class Presentational extends React.Component { constructor(props) { super(props); this.state = { input: '', messages: [] } this.handleChange = this.handleChange.bind(this); this.submitMessage = this.submitMessage.bind(this); } handleChange(event) { this.setState({ input: event.target.value }); } submitMessage() { this.setState((state) => { const currentMessage = state.input; return { input: '', messages: state.messages.concat(currentMessage) }; }); } render() { return (

Type in a new Message:


); } }; // React-Redux: const mapStateToProps = (state) => { return { messages: state } }; const mapDispatchToProps = (dispatch) => { return { submitNewMessage: (newMessage) => { dispatch(addMessage(newMessage)) } } }; const Provider = ReactRedux.Provider; const connect = ReactRedux.connect; // Define the Container component here: class AppWrapper extends React.Component { constructor(props) { super(props); } render() { // Complete the return statement: return (null); } }; ``` # --solutions-- ```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: class Presentational extends React.Component { constructor(props) { super(props); this.state = { input: '', messages: [] } this.handleChange = this.handleChange.bind(this); this.submitMessage = this.submitMessage.bind(this); } handleChange(event) { this.setState({ input: event.target.value }); } submitMessage() { this.setState((state) => { const currentMessage = state.input; return { input: '', messages: state.messages.concat(currentMessage) }; }); } render() { return (

Type in a new Message:


); } }; // React-Redux: const mapStateToProps = (state) => { return { messages: state } }; const mapDispatchToProps = (dispatch) => { return { submitNewMessage: (newMessage) => { dispatch(addMessage(newMessage)) } } }; const Provider = ReactRedux.Provider; const connect = ReactRedux.connect; const Container = connect(mapStateToProps, mapDispatchToProps)(Presentational); class AppWrapper extends React.Component { constructor(props) { super(props); } render() { return ( ); } }; ```