Sono ancora molto un reagente/ridondante noob. In una pagina ho un sacco di input di testo. Dopo un po 'ho iniziato a notare il mio file azione ha funzioni che fanno la stessa cosa, ma per i diversi ingressi:Condivisione di azioni e riduttori con reazione/ridondanza
export function setInputName(string) {
return {
type: 'SET_CURRENT_NAME',
payload: {value: string}
};
}
export function setInputCity(string) {
return {
type: 'SET_CURRENT_CITY',
payload: {value: string}
};
}
Con la mia riduttore di ricerca come:
export function currentName(state='', {type, payload}) {
switch (type) {
case 'SET_CURRENT_NAME':
return payload.value;
default:
return state;
}
}
export function currentCity(state='', {type, payload}) {
switch (type) {
case 'SET_CURRENT_CITY':
return payload.value;
default:
return state;
}
}
E la mia componente avuto questi ingressi multipli:
import {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {setInputName, setInputCity} from 'actions/form';
export default class Form extends Component {
static propTypes = {
setInputName: PropTypes.func.isRequired,
setInputCity: PropTypes.func.isRequired,
currentName: PropTypes.string.isRequired,
currentCity: PropTypes.string.isRequired
}
render() {
let {setInputName, setInputCity, currentName, currentCity} = this.props;
return (
<div>
<input
type="text"
placeholder="Name"
onChange={(e) => setInputName(e.currentTarget.value)}
value={currentName}
/>
<input
type="text"
placeholder="City"
onChange={(e) => setInputCity(e.currentTarget.value)}
value={currentCity}
/>
</div>
);
}
}
function select(state) {
return {
currentName: state.form.currentName,
currentCity: state.form.currentCity
};
}
function actions(dispatch) {
return bindActionCreators({
setInputName: setInputName,
setInputCity: setInputCity,
}, dispatch);
}
export default connect(select, actions)(Form);
Quale non è molto ASCIUTTO e ho subito pensato che stavo facendo qualcosa di sbagliato. C'è un buon modo per avere un'azione comune setInputValue
per tutti gli input di testo su ogni pagina e componente della mia app? Vorrei anche usare un riduttore comune per ogni input. Grazie.
UPDATE
Ecco il mio esempio lordo che funziona, ma mi sento come questo è ancora un po 'contorta e ci deve essere un modo migliore. Fondamentalmente nel riduttore controllo per vedere se quell'input è stato usato e aggiunto allo stato ancora. Se no, lo aggiungo. Se è così, aggiorno solo il suo valore. EDIT Ho mentito che questo in realtà non funziona.
// actions
export function updateTextInput(name, value) {
return {
type: 'SET_CURRENT_TEXT_INPUT',
payload: {name: name, value: value}
};
}
// reducer
export function currentTextInput(state=[], {type, payload}) {
switch (type) {
case 'SET_CURRENT_TEXT_INPUT':
let newState = state;
let curInput = state.findIndex(function(elem) {
return elem.name === payload.name;
});
if (curInput === -1) {
newState.push({name: payload.name, value: payload.value});
} else {
newState[curInput].value = payload.value;
}
return newState;
default:
return state;
}
}
// component
...
render() {
let {updateTextInput, currentTextInput} = this.props;
return (
<div>
<input
type="text"
placeholder="Name"
onChange={(e) => updateTextInput('name', e.currentTarget.value)}
value={currentTextInput.name}
/>
<input
type="text"
placeholder="City"
onChange={(e) => updateTextInput('city', e.currentTarget.value)}
value={currentTextInput.city}
/>
</div>
);
}
...
Questo chiarisce un po 'le cose. Cosa accadrebbe se avessi più moduli non correlati su una pagina e non avessi un modello specifico da cui partire? Potrei comunque utilizzare un comune azione/riduttore in qualche modo? Senza avere un modello gianormous per l'intera pagina. –
Ogni modello dovrebbe avere il proprio riduttore che riceve la propria porzione di stato. Potresti comunque avere una singola funzione di aggiornamento che può essere importata e utilizzata nei vari riduttori – slightlytyler