2016-01-27 29 views
14

Sto lavorando al mio primo progetto React/Redux e ho una piccola domanda. Ho letto la documentazione e ho visto le esercitazioni disponibili al numero https://egghead.io/lessons/javascript-redux-generating-containers-with-connect-from-react-redux-visibletodolist.React & Redux: connect() a più componenti e buone pratiche

Ma ho ancora una domanda. Si tratta di una pagina di accesso. quindi ho una di presentazione componente denominato LoginForm:

componenti/LoginForm.js

import { Component, PropTypes } from 'react' 

class LoginForm extends Component { 
    render() { 
     return (
     <div> 
      <form action="#" onSubmitLogin={(e) => this.handleSubmit(e)}> 
       <input type="text" ref={node => { this.login = node }} /> 
       <input type="password" ref={node => { this.password = node }} /> 
       <input type="submit" value="Login" /> 
      </form> 
     </div> 
    ) 
    } 

    handleSubmit(e) { 
     e.preventDefault(); 
     this.props.onSubmitLogin(this.login.value, this.password.value); 
    } 
} 

LoginForm.propTypes = { 
    onSubmitLogin: PropTypes.func.isRequired 
}; 

export default LoginForm; 

E un componente contenitore denominato Accesso cui passano i dati al mio componente. Utilizzando reagire-redux-router, io chiamo questo contenitore (e non il componente presentationnal):

contenitori/Login.js

import { connect } from 'react-redux' 
import { login } from '../actions/creators/userActionCreators' 
import LoginForm from '../components/LoginForm' 

const mapDispatchToProps = (dispatch) => { 
    return { 
     onSubmitLogin: (id, pass) => dispatch(login(id, pass)) 
    } 
}; 

export default connect(null, mapDispatchToProps)(LoginForm); 

Come potete vedere, sto usando il metodo connect fornire da redux per creare il mio contenitore.

La mia domanda è la seguente:

Se voglio che il mio contenitore login per usare viste multiple (ad esempio: LoginForm e ErrorList per visualizzare gli errori), ho bisogno di farlo a mano (senza collegamento, perché collegare take solo un argomento). Qualcosa di simile:

class Login extends Component { 

    render() { 
     return (
     <div> 
      <errorList /> 
      <LoginForm onSubmitLogin={ (id, pass) => dispatch(login(id, pass)) } /> 
     </div> 
    ) 
    } 

} 

È una cattiva pratica? È preferibile creare un altro componente di presentazione (LoginPage) che utilizza sia errorList che LoginForm e crea un contenitore (Login) che connect in LoginPage?


EDIT: Se creo un terzo componente di presentazione (LoginPage), dovrò per passare i dati due volte. Così: Container -> LoginPage -> LoginForm & ErrorList. Anche con contesto, non sembra essere la strada da percorrere.

risposta

25

Penso che quello che hai nel tuo secondo esempio sia molto vicino. È possibile creare un solo componente contenitore collegato e rendere più componenti di presentazione.

Nel vostro primo esempio, c'è in realtà non è un componente contenitore separato:

import { connect } from 'react-redux' 
import { login } from '../actions/creators/userActionCreators' 
import LoginForm from '../components/LoginForm' 

const mapDispatchToProps = (dispatch) => { 
    return { 
     onSubmitLogin: (id, pass) => dispatch(login(id, pass)) 
    } 
}; 

// `LoginForm` is being passed, so it would be the "container" 
// component in this scenario 
export default connect(null, mapDispatchToProps)(LoginForm); 

Anche se è in un modulo separato, quello che stai facendo qui si connette la vostra LoginForm direttamente.

Invece, ciò che si può fare è qualcosa di simile:

contenitori/Login.js

import { connect } from 'react-redux' 
import { login } from '../actions/creators/userActionCreators' 
import LoginForm from '../components/LoginForm' 
import ErrorList from '../components/ErrorList' 

class Login extends Component { 

    render() { 
     const { onSubmitLogin, errors } = this.props; 

     return (
     <div> 
      <ErrorList errors={errors} /> 
      <LoginForm onSubmitLogin={onSubmitLogin} /> 
     </div> 
    ) 
    } 

} 

const mapDispatchToProps = (dispatch) => { 
    return { 
     onSubmitLogin: (id, pass) => dispatch(login(id, pass)) 
    } 
}; 

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

export default connect(mapStateToProps, mapDispatchToProps)(Login); 

Nota che il componente Login è ora passato a connect, diventando così il "contenitore "componente e quindi sia errorList sia LoginForm possono essere presenti. Tutti i loro dati possono essere passati tramite oggetti di scena dal contenitore Login.

+1

Molto utile. Scusa per il ritardo, grazie! – Armelias

-1

Credo davvero che sia necessario creare tutti i componenti come componenti di presentazione. Al momento è necessario un componente contenitore, è possibile utilizzare {connect} su uno dei Presentational esistenti e convertirli in uno Container.

Ma questa è solo la mia opinione con una breve esperienza in React finora.

Problemi correlati