Redux窗体不会重置
问题描述:
我有一个基于道具的组件可以渲染一个带有不同组件的窗体。Redux窗体不会重置
class Feedback extends Component {
submitMyForm(data) {
const { onSubmit, reset } = this.props;
reset();
return onSubmit(data);
//
// do other success stuff
}
render() {
const { handleSubmit } = this.props;
let component;
if(this.props.data.feedbackType == "likert")
component = Likert;
else if(this.props.data.feedbackType == "single choice")
component = SingleChoice;
else if(this.props.data.feedbackType == "multiple choice")
component = MultipleChoice;
return (
<div>
<h1>Feedback zu Aufgabe {this.props.id}</h1>
<form onSubmit={handleSubmit(this.submitMyForm.bind(this))}>
<Field
name="feedback"
component={component}
heading={this.props.data.description}
items={this.props.data.options}
required={true}
/>
<button type="submit">Submit</button>
</form>
</div>
);
}
}
// Decorate the form component
Feedback = reduxForm({
form: 'feedback', // a unique name for this form,
validate,
enableReinitialize:true
})(Feedback);
function validate(formProps) {
const errors = {};
if (!formProps.feedback) {
errors.feedback = 'please select an option';
}
return errors;
}
export default Feedback;
import React, { PropTypes } from 'react';
const SingleChoice = ({ input, disabled, heading, required, className, items, name, meta: { touched, error } }) => (
<fieldset className={`form__field ${className || ''}`}>
<legend className="form__label">
{heading}{required ? (<span>*</span>) : null}
{ (touched && error) ? (
<span className="form__error"> {error}</span>
) : null }
</legend>
<div>
{ items.map((item, i) => (
<div className="form__segmented-control width-1/[email protected]" key={ i }>
<input
{...input}
name={ name }
type="radio"
value={ item.value }
disabled={ disabled }
className="segmented-control__input u-option-bg-current"
id={ `${name}-${item.value}` }
/>
<label className="segmented-control__label u-adjacent-current" htmlFor={ `${name}-${item.value}` }>
{item.label}
</label>
</div>
))
}
</div>
</fieldset>
);
SingleChoice.propTypes = {
input: PropTypes.object.isRequired,
name: PropTypes.string.isRequired,
className: PropTypes.string,
items: PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.any.isRequired,
})).isRequired,
heading: PropTypes.string,
meta: PropTypes.object,
required: PropTypes.bool,
disabled: PropTypes.bool,
};
export default SingleChoice;
第一次表单渲染一切都很好。所有单选按钮都未选中,如果我尝试提交它,我会收到验证错误。但是当我的Feeback组件收到新的道具并且表单被更新时。当新道具的表单组件与旧道具的表单组件相同时,旧值仍然保持选中状态。
当新的道具的表单组件不同时,所有的值都不是按照预期选择的,但是我可以在不选择任何内容的情况下提交表单,这应该通过验证来阻止。
我希望你有任何建议,我完全没有想法在这一点上。
答
当我的Feeback组件接收到新的道具并且窗体被更新时,当新道具的窗体组件与旧道具相同时,旧值仍然保持选中状态。
这是因为feedback
表单的值存储在Redux存储区中。
您应该执行componentWillReceiveProps
并测试您的表单是否应该重置。
class Feedback extends Component {
componentWillReceiveProps (nextProps) {
if (nextProps.blabla !== this.props.blabla) {
// oh cool, props changed, let's reset the form
// checkout more available form props at http://redux-form.com/6.4.3/docs/api/ReduxForm.md/
this.props.reset();
}
}
render() {
// your normal rendering function
}
}
答
最好的方法,我发现:
进口“初始化” ......
import {initialize} from 'redux-form';
,然后当你打电话的动作,传递一个空对象到之后调用另一个动作'初始化'功能...
yourFunction = (data) => {
this.props.dispatch(yourAction(data))
.then(
result => {
if (result) {
this.props.dispatch(initialize('nameOfTheForm', {}));
}
}
);
如果您设置一个可以复制问题的小工具,您将收到更有可能的答案。我已经在webpackbin中为你设置了所有的样板文件,所以在那里重现你的问题。或者使用您选择的任何其他提琴手。我的样板位于http://www.webpackbin.com/NJ2Nd-0QG请注意,保存更改后网址会发生变化,因此请包含更新后的网址。 – Anarion
感谢您的回复。我现在感到有点愚蠢,这从来没有发生过我。由于某种原因,这个问题在向我的项目中添加material-ui后神奇地解决了。但我下次肯定会这样做。感谢您的建议! – Rothkrebschen