Я все еще очень реагирую/уменьшаю noob. На одной странице у меня тонна текстовых входов. Через некоторое время я начал замечать мой файл действие имеет функции делают то же самое, но для разных входов:Совместное действие и редукторы с реакцией/редукцией
export function setInputName(string) {
return {
type: 'SET_CURRENT_NAME',
payload: {value: string}
};
}
export function setInputCity(string) {
return {
type: 'SET_CURRENT_CITY',
payload: {value: string}
};
}
С моим Редуктор выглядит как:
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;
}
}
И мой компонент имел эти несколько входов:
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);
Это не очень СУХОЙ, и я сразу же подумал, что делаю что-то неправильно. Есть ли хороший способ иметь общее действие setInputValue
для всех текстовых входов на каждой странице и компоненте моего приложения? Я также хотел бы использовать общий редуктор для каждого входа. Спасибо.
UPDATE
Вот мой пример валовый, который работает, но я чувствую, что это еще немного запутанное и там должно быть лучшим способом. В основном в редукторе я проверяю, был ли этот вход использован и добавлен в состояние еще. Если нет, добавьте его. Если это так, я просто обновляю его значение. EDIT Я солгал, что на самом деле это не работает.
// 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>
);
}
...
Это проясняет ситуацию совсем немного. Что делать, если у меня было несколько несвязанных форм на странице и у меня не было одной конкретной модели? Могу ли я по-прежнему использовать общее действие/редуктор? Без единой gianormous модели для всей страницы. –
Каждая модель должна иметь свой собственный редуктор, который получает свой собственный срез состояния. Однако вы можете использовать одну функцию обновления, которую можно импортировать и использовать в различных редукторах. – slightlytyler