【发布时间】:2017-04-25 21:59:56
【问题描述】:
问题
我有一份人员名单。我想:
- 点击用户名选择要编辑的用户。
- 编辑该用户的信息,以便我可以单击提交按钮并更新列表。
- 如果我单击其他姓名,我想切换到该人的信息,而不必先故意关闭表单。
在 #3 之前一切正常。当我点击另一个人时,表单本身不会更新。
我的代码
更新组件用于更新表单:
const UpdateForm = ({ updatePerson, personToUpdate, handleInputChange }) => {
let _name, _city, _age, _id;
const submit = (e) => {
e.preventDefault();
updatePerson({
name: _name.value,
city: _city.value,
age: _age.value,
_id: _id.value
});
};
return (
<div>
<form onSubmit={submit}>
<h3>Update Person</h3>
<label htmlFor="_id">Some Unique ID: </label>
<input type="text" name="_id" ref={input => _id = input} id="_id" defaultValue={personToUpdate._id} onChange={input => handleInputChange(personToUpdate)} required />
<br />
<label htmlFor="name">Name: </label>
<input type="text" name="name" ref={input => _name = input} id="name" defaultValue={personToUpdate.name} onChange={input => handleInputChange(personToUpdate)} />
<br />
<label htmlFor="city">City: </label>
<input type="text" name="city" ref={input => _city = input} id="city" defaultValue={personToUpdate.city} onChange={input => handleInputChange(personToUpdate)} />
<br />
<label htmlFor="age">Age: </label>
<input type="text" name="age" ref={input => _age = input} id="age" defaultValue={personToUpdate.age} onChange={input => handleInputChange(personToUpdate)} />
<br />
<input type="submit" value="Submit" />
</form>
</div>
);
};
export default UpdateForm;
Person 组件的相关部分:
class Person extends Component {
nameClick() {
if (this.props.person._id !== this.props.personToUpdate._id) {
this.props.setForUpdate(this.props.person);
this.forceUpdate();
}
else {
this.props.toggleUpdatePersonPanel();
}
}
render() {
return (
<div>
<span onClick={this.nameClick}>
{this.props.person.name} ({this.props.person.age})
</span>
</div>
);
}
}
export default Person;
PeopleList 的相关部分,其中包含 Persons:
class PeopleList extends Component {
render() {
return(
<div>
{this.props.people.map((person) => {
return <Person
key={person._id}
person={person}
updatePersonPanel={this.props.updatePersonPanel}
setForUpdate={this.props.setForUpdate}
personToUpdate={this.props.personToUpdate}
/>;
})}
</div>
);
}
} // end class
export default PeopleList;
Form Reducer,仅包含相关操作:
export default function formReducer(state = initialState.form, action) {
let filteredPeople;
switch (action.type) {
case TOGGLE_UPDATE_PANEL:
return Object.assign({}, state, { updatePersonPanel: false }, { personToUpdate: {
_id: "",
name: "",
city: "",
age: ""
}});
case SET_FOR_UPDATE:
return Object.assign({}, state, { personToUpdate: action.person }, { updatePersonPanel: true });
case UPDATE_RECORD:
filteredPeople = state.people.filter((person) => {
return person._id === action.person._id ? false : true;
}); // end filter
return Object.assign({}, state, { people: [ ...filteredPeople, action.person] }, { personToUpdate: {
_id: "",
name: "",
city: "",
age: ""
}}, { updatePersonPanel: false });
case HANDLE_INPUT_CHANGE:
return Object.assign({}, state, { personToUpdate: action.person });
default:
return state;
}
}
我的初始状态文件的相关部分:
form: {
people: [
{
_id: "adfpnu64",
name: "Johnny",
city: "Bobville",
age: 22
},
{
_id: "adf2pnu6",
name: "Renee",
city: "Juro",
age: 21
},
{
_id: "ad3fpnu",
name: "Lipstasch",
city: "Bobville",
age: 45
}
],
updatePersonPanel: false,
personToUpdate: {
_id: "",
name: "",
city: "",
age: ""
},
}
解决方案的尝试(到目前为止)
- 我试图通过将表单属性切换为
value而不是defaultValue,使该组件成为一个完全受控的组件。当我这样做时,名称切换得很好,但形式变得不可更改且无用。
我的问题
几乎所有此类问题的解决方案都推荐使用 redux-form 或提供 two-way binding solutions that work fine in React without reduce。 我想知道如何在不使用 redux-form 或其他任何可能的情况下使用 Redux 来做到这一点。有没有办法在不触及生命周期方法的情况下解决这个问题?
结论(目前)
好吧,现在,我决定让我的表单不受控制,并使用一些经典的 Js DOM 方法和生命周期方法来控制表单。无论出于何种原因,一旦我使用了一些答案建议,我的浏览器就会耗尽我的 CPU 并崩溃,大概是因为存在某种无限循环。如果有人有进一步的建议,我将不胜感激。现在我满足于这个:
class UpdateForm extends Component {
constructor(props){
super(props);
this.submit = this.submit.bind(this);
}
componentWillReceiveProps(nextProps) {
if (nextProps.personToUpdate._id !== this.props.personToUpdate._id) {
document.getElementById("name").value = nextProps.personToUpdate.name;
document.getElementById("age").value = nextProps.personToUpdate.age;
document.getElementById("city").value = nextProps.personToUpdate.city;
}
}
submit(e) {
e.preventDefault();
this.props.updatePerson({
name: document.getElementById("name").value,
city: document.getElementById("city").value,
age: document.getElementById("age").value,
_id: this.props.personToUpdate._id
});
}
render() {
return (
<div>
<form onSubmit={this.submit}>
<h3>Update Person</h3>
Unique ID: {this.props.personToUpdate._id}
<br />
<label htmlFor="name">Name: </label>
<input type="text" name="name" id="name" ref="name" defaultValue={this.props.personToUpdate.name} required />
<br />
<label htmlFor="city">City: </label>
<input type="text" name="city" id="city" ref="city" defaultValue={this.props.personToUpdate.city} required />
<br />
<label htmlFor="age">Age: </label>
<input type="text" name="age" id="age" ref="age" defaultValue={this.props.personToUpdate.age} required />
<br />
<input type="submit" value="Update" />
</form>
</div>
);
}
} // end class
export default UpdateForm;
我将很快探索redux-form,因为很明显,作为输入和输出的表单是一项不稳定的业务。目前,我的小应用程序可以运行。
【问题讨论】:
标签: javascript forms reactjs redux react-redux