2015-10-20 16 views
13

Attualmente sto affrontando questo problema progettando un'applicazione React e non riesco a trovare una risposta.Come inviare le azioni dai componenti secondari a tre livelli inferiori?

Quindi la mia domanda è seguente gerarchia dei componenti in Reagire Router

App -> DynamicContainer -> -> LoginComponent

Ora, LoginComponents presenta elementi modulo per tener username e password.

Ho userActionCreators in cui viene gestito il login e invia correttamente il login al termine, ma non riesco a trovare il modo giusto per connettere il mio account di accesso alle azioni di invio o chiamare actionCreators.

Come faccio? Qualsiasi suggerimento sarebbe apprezzato.

risposta

16

Un'opzione è quella di associare i moduli monouso alle loro azioni con connect. Dal momento che <LoginComponent /> è tipicamente facendo sempre la stessa cosa, è possibile utilizzarlo in questo modo:

import React from 'react'; 
import * as userActionCreators from '../actions/users'; 
import { connect } from 'react-redux'; 

export class LoginComponent extends React.Component { 
    static propTypes = { 
    login: React.PropTypes.func.isRequired 
    } 

    render() { 
    const { login } = this.props; 
    const { username, password } = this.state; 

    return (
     <form onSubmit={() => login(username, password) }> 
     ... 
     </form> 
    ); 
    } 
} 

export default connect(null, userActionCreators)(LoginComponent); 

connect lega automaticamente il creatore azione e separatamente fornisce dispatch a props, quindi se volete essere più espliciti, l'esempio precedente è la stessa

import React from 'react'; 
import { login } from '../actions/users'; 
import { connect } from 'react-redux'; 

export class LoginComponent extends React.Component { 
    static propTypes = { 
    dispatch: React.PropTypes.func.isRequired 
    } 

    render() { 
    const { login, dispatch } = this.props; 
    const { username, password } = this.state; 

    return (
     <form onSubmit={() => dispatch(login(username, password)) }> 
     ... 
     </form> 
    ); 
    } 
} 

export default connect()(LoginComponent); 

E per riferimento, userActionCreators:

const LOGIN_SUCCESS = 'LOGIN_SUCCESS'; 
const LOGIN_FAILED = 'LOGIN_FAILED'; 

export function login(username, password) { 
    if (username === 'realUser' && password === 'secretPassword') { 
    return { type: LOGIN_SUCCESS, payload: { name: 'Joe', username: 'realUser' } }; 
    } else { 
    return { type: LOGIN_FAILED, error: 'Invalid username or password }; 
    } 
} 
+0

Grazie! Potresti aggiungere per rispondere come dovrebbe apparire 'userActionCreators'? – vitalets

+2

Ho aggiunto l'esempio 'userActionsCreators' ed espanso su' connect' –

+1

Grazie per l'aiuto, nel blocco del codice sorgente hai dimenticato di estrarre 'dispatch' da' this.props'. –

0

due opzioni:

  1. passare un actionCreator vincolato dal contenitore (che è collegato a Redux) fino a un componente figlio (che non è collegato a Redux) tramite l'oggetto props.

  2. Considerare l'adozione di React Component Context nel progetto.

+0

Come posso passare boundActionCreator quando l'heirarchy è definita da react-router in cui un componente figlio diverso è collegato a DynamicContainer Component che funge da segnaposto. Ho appena {this.props.children} all'interno di DynamicContainer Component. – Nitesh

+0

Quindi stai provando a passare i creatori di azioni dalla radice della tua applicazione attraverso la reazione del router in un componente del modulo di login di qualche tipo? – ctrlplusb

6

se ho capito bene, se leggi Example: Todo List | Redux troverai l'esempio che potresti cercare.

C'è il componente App, connect() Ed a Redux, e poi ci sei gli altri componenti: AddTodo, ToDoList, Todo e Footer.

App chiama ToDoList che chiama Todo dove l'utente può cliccare su qualcosa.Questa click navigare di nuovo richiamata dopo la richiamata, da Todo a ToDoList a App come di seguito dettagliato:

  1. App chiama ToDoList con <TodoList todos={visibleTodos} onTodoClick={ index => dispatch(completeTodo(index)) } />

  2. ToDoList chiama Todo con <Todo {...todo} key={index} onClick={() => this.props.onTodoClick(index) } />

  3. Todo componente ha un <li> con onClick={this.props.onClick} proprietà.

Quindi, al contrario, quando someones clic all'interno della Todo intelaiature, blocchi che chiamerà this.props.onClick che chiamerà this.props.onTodoClick(index) da ToDoList (notare il parametro aggiunto opzionale indice), poi, finalmente, questo invocherà la funzione dispatch(completeTodo(index)) dall'app .

Problemi correlati