2015-10-29 15 views
9

Ho iniziato a utilizzare Redux con React e lo adoro assolutamente. Tuttavia, il problema che sto avendo al momento è che oltre allo stato, ho anche più informazioni che ho bisogno di memorizzare/utilizzare nella mia applicazione.Uso di Redux con i modelli

In questo caso specifico, ho un modello con stato recuperato da un'API. Questo modello ha anche alcune informazioni su se stesso, ad es. come si visualizza una proprietà sullo schermo "name" => "Name of the blabla". Capisco come lavorare con State usando Redux, ma ho difficoltà a vedere cosa fare con queste altre informazioni che ho ancora bisogno di propagare in tutta l'applicazione, ma non è in realtà stato.

+0

A prima vista, che sembra come stato per me. Quale obiezione hai per mettere il nome in stato? –

+0

Il nome stesso è effettivamente stato, tuttavia l'"etichetta" di quella proprietà nome non è stato. Sono informazioni sulle proprietà nel modello. –

+0

Se la "etichetta" del nome è usata come oggetto di scena in un componente, direi che è lo stato. –

risposta

11

Secondo Redux, lo Stato è l'unica "fonte di verità". E non dovrebbe avere duplicazione (che porterebbe a incongruenze).

Pertanto, il proprio stato deve memorizzare name, ma non la proprietà dell'etichetta calcolata .

In effetti, "Nome del blabla" è una funzione (nel senso matematico) del valore Nome e se differiscono (ad esempio, se ad un certo punto nome === 'foo' ma l'etichetta è ' Nome della barra "invece di" Nome del foo "), quindi hai un problema ...

Quindi, quello che vorrei fare è archiviare il minimo nel tuo stato (nome in quel caso) e calcolare l'etichetta direttamente nel componente, dove ne hai bisogno.

Se è necessario riutilizzarlo, quindi creare un componente che prende solo il tuo nome come supporto e rendere una stringa con "Nome della blablaba" (se nome = blabla suppongo).

Se hai bisogno di calcoli più complessi (ad esempio hai più etichette, calcoli di date, ecc.), Puoi sempre creare una funzione che prende il tuo stato in input e sputare il tuo "Modello" in uscita con tutto calcolato.

Redux è molto funzionale in natura, così si potrebbe anche abbracciarlo :)

+0

Credo di preferire questo approccio. –

+0

Perché non possiamo lasciare che la sottostruttura di stato sia di per sé un modello immutabile? – Nishant

6

So Sono un po 'in ritardo alla festa, ma ho pensato che qualcuno potrebbe utilizzare la risposta. Che cosa ha funzionato per me fino a questo punto dopo aver lavorato con Reagire da qualche anno è quello di avere una struttura che è un po 'come questo:

  • Stato: che definisce la struttura (o 'schemi') dei miei dati.
  • Azioni: apportare modifiche a questo stato. Queste azioni possono gestire le operazioni di sincronizzazione o asincrone.
  • Saghe: gestiscono azioni asincrone.
  • Selettori: gestiscono la struttura dei dati di cui ho bisogno per la vista/per l'API.
  • Costanti: altri dati che non cambieranno nel tempo e che non hanno senso aggiungere al mio stato.

Quindi, dopo aver detto che il flusso delle mie applicazioni è qualcosa di simile: Un ACTION viene spedito => Se l'azione è asincrono un SAGA è in ascolto e si esegue l'operazione di recupero => Questa saga salva gli aggiornamenti per il STATE => [Reagire il livello componenti da ora in poi] => Se la mia vista ha bisogno dei dati dal mio stato in un formato diverso per qualsiasi motivo, la invio tramite un SELECTOR che cambierà quel formato => Quindi allego questi nuovi dati analizzati a il mio componente del contenitore.

Un altro flusso potrebbe essere quello in cui sono necessari dati statici che non si trovano nello state. In questa causa lo salverei in un oggetto in un file separato e lo importerei direttamente nel mio componente contenitore (non importerei mai nulla nei miei componenti figlio/presentazione direttamente.) Solo altri componenti. I dati sono gestiti in un livello separato rispetto al componenti).

Un terzo tipo di flusso che posso pensare in questo momento è quando è necessario eseguire un POST sulla propria API e per qualsiasi motivo i dati nel proprio stato necessitano di un'analisi prima di procedere. In tal caso, farei lo stesso che nel primo esempio, ma viceversa: invia un ACTION => che viene gestito da un SAGA => prima di eseguire il recupero, porterei i miei dati già strutturati per il mio POST (le saghe hanno un metodo chiamato select per aiutarti a utilizzare i selettori qui) => quindi eseguirò l'operazione asincrona => aggiorna lo stato di conseguenza.

Nel caso in cui non sai cosa intendo per selettori o saghe alcuni Puntano qui:

1

Credo che i modelli sono necessari per un'applicazione basata su Redux come per qualsiasi altro sistema.

I modelli sono il vocabolario di un sistema. I modelli portano sanità mentale al codice base. Senza di loro una base di codice sembra una serie di pensieri distorti folle.

È possibile utilizzare le funzioni di stato per soddisfare le necessità dei modelli nelle app ReactJS + Redux. Proprio come i modelli contengono dati e metodi, questi oggetti contengono solo le funzioni che possono essere applicate allo stato.

Leggi qui: https://medium.com/@nshnt/state-functions-for-modeling-with-redux-a9b9d452a631.

Ecco il famoso esempio app Redux TODO con funzioni di stato:

todo_reducer.js:

import TODO from './todo_state'; 

const todoListReducer = (state=TODO.initialState(), action)=>{ 
    switch(action.type){ 

    case 'ADD_TODO' : 
     return TODO.addTask(state, action.taskName); 

    case 'FINISHED_TODO': 
     return TODO.setFinished(state, action.taskID); 

    case 'PENDING_TODO': 
     return TODO.setPending(state, action.taskID); 

    default : 
     return state; 
    } 
}; 

export default todoListReducer; 

todo-state.js:

export default { 
    initialState:() => [], 

    addTask: (todoList, name)=> todoList.concat({id: todoList.length, name: name}), 

    setFinished: (todoList, taskId) => (
     todoList.map(task=> task.id === taskId ? {...task, complete: true} : task) 
), 

    setPending: (todoList, taskId) => (
     todoList.map(task=> task.id === taskId ? {...task, complete: false} : task) 
), 

    pending: todoList=> todoList.filter(task=> !task.complete) 

}; 

anche io usa queste funzioni di stato nel componente, se il componente necessita di qualche manipolazione di stato.

todo_list.js:

import React from 'react'; 
import {connect} from 'react-redux'; 
import TODO from './todo_state'; 

const TodoList = ({tasks, showCompletedTasks, toggleTodo})=> { 
    const toListElement = (task) => (
     <li key={task.id}> 
     <input type="checkbox" checked={task.complete} onChange={(e)=> toggleTodo(task)}/> 
     <label>{task.name} {task.complete ? "Complete" : "Pending"}</label> 
     </li> 
); 
    const visibleTaskList = 
     (showCompletedTasks ? tasks 
     : TODO.pending(tasks)).map(toListElement); 

    return (
     <ul className="todo-list"> 
     {visibleTaskList} 
     </ul> 
); 
} 
..... 
export default connect(mapStateToProps, mapDispatchToProps)(TodoList);