Поскольку упомянутая ошибка actions
должна быть простым объектом, но когда вы объединяете функции в цепочку, вы фактически передаете function
(следующий в цепочке), а не object
.
Проблема здесь для вас заключается в том, что вы хотите передать дополнительный аргумент в дополнение к фактическому событию DOM
, например, имя input
, то есть: "пароль", "пользователь" и т. Д ...
Тогда почему бы просто не дать input
имя и захватить его в функции создателя действия (так же, как вы делаете это с атрибутом value
).
Ваша форма может выглядеть примерно так:
const Form = ({ inputChange, form }) => (
<div>
<input name="user" onChange={inputChange} type="text" value={form.user} />
<input name="password" onChange={inputChange} type="password" value={form.password} />
</div>
);
const mapState = state => ({
form: state
});
const mapDispatch = {
inputChange
};
const ConnectedForm = connect(
mapState,
mapDispatch
)(Form);
И внутри вашего создателя действия:
const inputChange = ({ target }) => ({
type: INPUT_CHANGE,
payload: {
value: target.value,
inputName: target.name
}
});
и ваш редуктор может справиться с этим, что-то вроде этого:
const reducer = (state = {user: '', password: ''}, action) => {
switch (action.type) {
case INPUT_CHANGE: {
const { inputName, value } = action.payload;
return {
...state,
[inputName]: value
};
}
default:
return state;
}
};
Пример выполнения:
// mimic imports
const { createStore } = Redux;
const { Provider, connect } = ReactRedux;
const INPUT_CHANGE = "INPUT_CHANGE";
const reducer = (state = {user: '', password: ''}, action) => {
switch (action.type) {
case INPUT_CHANGE: {
const { inputName, value } = action.payload;
const nextState = {
...state,
[inputName]: value
};
console.clear();
console.log('store', nextState);
return nextState;
}
default:
return state;
}
};
const inputChange = ({ target }) => ({
type: INPUT_CHANGE,
payload: {
value: target.value,
inputName: target.name
}
});
const store = createStore(reducer);
const Form = ({ inputChange, form }) => (
<div>
<input name="user" onChange={inputChange} type="text" value={form.user} />
<input name="password" onChange={inputChange} type="password" value={form.password} />
</div>
);
const mapState = state => ({
form: state
});
const mapDispatch = {
inputChange
};
const ConnectedForm = connect(
mapState,
mapDispatch
)(Form);
class App extends React.Component {
render() {
return (
<div>
<ConnectedForm />
</div>
);
}
}
const root = (
<Provider store={store}>
<App />
</Provider>
);
const rootElement = document.getElementById("root");
ReactDOM.render(root, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.1/redux.min.js
"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.4.10/react-redux.min.js"></script>
<div id="root"/>