使用一个函数输入多个输入来更新Redux中的对象状态的最佳方法是什么?
我有3个输入-如果可能的话,我想使用一个函数或最佳实践将对应的输入字段更新为redux对象字段。
// Contact.js
this.state = {
contactInfo: {
firstName: '',
address: '',
city: '',
}
}
onChangeInfo = (event, action) => {
const { dispatch } = this.props;
const { contactInfo } = this.state;
// Is this an issue?
contactInfo[event.target.name] = event.target.value;
if (action === 'CHANGE') {
dispatch(updateContactInfo(contactInfo));
this.setState({ contactInfo });
} else {
this.setState({ contactInfo });
}
}
render() {
const { firstName, address, city } = this.state.contactInfo;
return (
<div>
<div>
<input placeholder=" " type="text" name='firstName' value={firstName} onChange={(e) => this.onChangeInfo(e, 'CHANGE')} required id="" />
<div className="placeholder"><span>First & last name</span></div>
</div>
<div>
<input placeholder=" " type="text" name="address" value={address} onChange={(e) => this.onChangeInfo(e, 'CHANGE')} required id="" />
<div className="placeholder"><span>Address</span></div>
</div>
<div>
<input placeholder=" " type="text" name="city" value={city} onChange={(e) => this.onChangeInfo(e, 'CHANGE')} required id="" />
<div className="placeholder"><span>City</span></div>
</div>
</div>
)}
//减速器
const initialState = {
contactInformation: [],
}
export default function (state, action) {
state = state === undefined ? initialState : state;
switch (action.type) {
case 'CONTACT_INFO': {
state.contactInformation.test.info = payload;
return Object.assign({}, state, action.payload);
}
default: return state;
}
}
答案 0 :(得分:1)
我建议您保持三种不同的操作作为最佳实践 因为动作始终是纯函数,并且特定于一个特定操作。
export const firstName = (firstName) => ({
type : 'FIRST_NAME',
payload : firstName
});
export const address = (address) => ({
type : 'ADDRESS',
payload : address
});
export const city = (city) => ({
type : 'CITY',
payload : city
});
然后,在减速器中,根据action.type更新商店。
答案 1 :(得分:1)
我看不到using setState
in this case的重点
this.state = {
contactInfo: {...this.props}
}
onChangeInfo = ({target: {name, value}}, action) => {
const { dispatch } = this.props;
const contactInfo = {[name]: value};
if (action === 'CHANGE') {
dispatch(updateContactInfo(contactInfo));
}
}
示例
const { Component, useState, useEffect } = React;
const { bindActionCreators, combineReducers, createStore, applyMiddleware, compose } = Redux;
const { connect, Provider } = ReactRedux;
const initalState = {
contactInfo: {
firstName: '',
address: '',
city: ''
}
}
const reducer = (state = initalState, action) => {
switch (action.type) {
case 'CONTACT_INFO': {
const newState = {
...state,
contactInfo: {
...state.contactInfo,
...action.payload.contactInfo
}
};
return newState;
}
default: return state;
}
}
const reducers = combineReducers({
reducer
})
const store = createStore(
reducers
);
const updateContactInfo = (payload) => ({
type: 'CONTACT_INFO', payload
})
const mapStateToProps = state => {
return {
contactInfo: state.reducer.contactInfo
}
}
const mapDispatchToProps = dispatch => ({
updateContactInfo: payload => dispatch(updateContactInfo(payload))
})
class _App extends Component {
constructor(props) {
super(props);
this.state = {...this.props}
this.updateContactInfo = this.props.updateContactInfo;
}
static getDerivedStateFromProps (props, state) {
return {...props}
}
onChangeInfo ({target: {name, value}}, action) {
const contactInfo = { contactInfo: {[name]: value}};
if (action === 'CHANGE') {
this.updateContactInfo(contactInfo);
}
}
render() {
const { firstName, address, city } = this.state.contactInfo;
return <div>
<div>
<input placeholder=" " type="text" name='firstName' value={firstName} onChange={(e) => this.onChangeInfo(e, 'CHANGE')} required id="" />
<div className="placeholder"><span>First & last name</span></div>
</div>
<div>
<input placeholder=" " type="text" name="address" value={address} onChange={(e) => this.onChangeInfo(e, 'CHANGE')} required id="" />
<div className="placeholder"><span>Address</span></div>
</div>
<div>
<input placeholder=" " type="text" name="city" value={city} onChange={(e) => this.onChangeInfo(e, 'CHANGE')} required id="" />
<div className="placeholder"><span>City</span></div>
</div>
{JSON.stringify(this.state)}
</div>
}
}
const App = connect(mapStateToProps, mapDispatchToProps)(_App)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.10.1/polyfill.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script src="https://unpkg.com/redux@4.0.5/dist/redux.js"></script>
<script src="https://unpkg.com/react-redux@latest/dist/react-redux.js"></script>
<div id="root"></div>
答案 2 :(得分:0)
好问题。
在给您答案之前,我必须指出几件事。在任何应用程序中,通常存在两种状态:长期状态和短暂状态(也称为短暂状态)。 Redux旨在充当您的容器,以放置您的所有长期状态,这些长期状态是您应用程序中不同部分通常关心的。
话虽如此,我可以看到您在应用程序中唯一要做的就是用用户输入来更新状态。我敢打赌,当用户单击“提交”按钮时,您可以使用该状态执行某些操作。如果是这种情况,那么根据定义,输入是短暂的,我不将输入状态全部放在Redux中。相反,当用户提交表单时,我只会触发1个操作。
<form onSubmit={onSubmitHandler}>
<input name="name" type="text" />
<input name="hobby" type="text" />
<button type="submit" />
<form />
------
// this is slight pseudo-code, but hopefully you get the gist
const onSubmitHandler = (event) => {
const myFields = // get fields from event object.
dispatch({type: 'SOME-ACTION', fields: myFields})
}
我还建议您考虑更改总体上对行为建模的方式。您可以看一下video,它超出了我的意思。