Redux-formを使用して以下の単純なフォームをレンダリングしていますが、うまく機能しています。ここで、もう1つの状況で送信ボタンを無効にしたいと思います。Field
のいずれかにエラーがある場合(つまり、meta.error
が設定されている場合)。
ドキュメントに目を通すことから、周囲の<form>
がその<Field>
コンポーネントにエラーがあるかどうかを知ることができないと思います。たぶん誰もがアイデアを持っている、disabled={hasErrors || submitting || pristine}
を使用するのと同じくらい簡単にそれを解決する方法
const EditBlogEntryForm = ({ onSubmit, reset, handleSubmit,
pristine, submitting, ...rest }) => {
console.log('rest: ', rest);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="form-group">
<Field name="title"
type="text"
component={renderField}
label="Titel"
className="form-control"
placeholder="Titel eingeben..." />
</div>
<div className="form-group">
<Field name="text"
component={renderTextArea}
label="Text"
className="form-control"
placeholder="Textinhalt eingeben..." />
</div>
<div className="form-group">
<Field name="image"
type="text"
component={renderField}
label="Bild-URL:"
className="form-control"
placeholder="Bildadresse eingeben..." />
</div>
<div>
<button type="submit" className="btn btn-default"
disabled={submitting || pristine}>
Blogeintrag speichern
</button>
<button type="button" className="btn btn-default"
disabled={pristine || submitting}
onClick={reset}>
Formular leeren
</button>
</div>
</form>
);
};
SetStateコンポーネントごとにthis.propsを使用するだけで必要な状態を悪用しないでください。もう一度レンダリングされます
const {invalid} = this.props
return(
<button type="submit" className="btn btn-default"
disabled={invalid|| submitting || pristine}>
Blogeintrag speichern
</button>)
その他のドキュメント: https://redux-form.com/6.0.0-alpha.4/docs/api/props.md/
Reduxフォームはすでに多くのプロパティをフォームに渡します。 1つはinvalid
です。これは、フィールド検証のいずれかが失敗したかどうかを判断し、送信を無効にするために使用しているものです。
できることは、Errors
と呼ばれる変数を用意することです。これは、API呼び出しにエラーが返されたときにtrueになります
constructor(super) {
this.state = {
errors: false,
}
}
componentWillReceiveProps(nextProps) {
const that = this;
if (nextProps.errors) {
that.setState({errors: true})
}
}
<button type="submit" className="btn btn-default"
disabled={this.state.errors || submitting || pristine}>
Blogeintrag speichern
</button>
アラステアは私を正しい方向に向けてくれました(ありがとうございます!)。これは、ローカルUI関連の状態が実際に非常に役立つケースの1つだと思います。そのため、SFCをリアクションクラスにリファクタリングしました。そのクラスのconstructor
とcomponentWillReceiveProps
は次のようになります。
constructor(props) {
super(props);
this.state = {
errors: false
};
}
componentWillReceiveProps(nextProps) {
if (nextProps.invalid) {
this.setState({errors: true});
} else {
this.setState({errors: false});
}
}
this.state.errors
ボタンを無効にすることは完全に機能しています。ご覧のとおり、invalid
propフォームは常に未定義であり、フォームが有効な場合は再度trueに設定することを忘れないため、error
propフォームredux-formを使用する必要がありました。さらに、答えでthis
参照をthat
にコピーした理由を知りません。まだ同じオブジェクトを指しているため、動作は変更されません。
可能性は、検証フィールドを使用することです。関数を定義する必要があります:
const required = value => (value ? undefined : 'Required')
そして、あなたのフィールドでこの関数を使用します:
<div className="form-group">
<Field name="title"
type="text"
component={renderField}
label="Titel"
className="form-control"
placeholder="Titel eingeben..."
validate={[required]}
/>
</div>
react-redux-form
ライブラリを使用している場合、最終的にフォームのonUpdate
イベントを使用してフォームの有効性状態をキャプチャし、このように非アクティブ化に使用できる内部状態変数を変更できますボタン。実行できることを示すサンプルコードを次に示します。
import React, { Component } from 'react';
import { Button, Modal, ModalHeader, ModalBody, Row, Label, Col } from 'reactstrap';
import { Control, LocalForm, Errors } from 'react-redux-form';
const required = (val) => val && val.length;
const maxLength = (len) => (val) => !(val) || (val.length <= len);
const minLength = (len) => (val) => (val) && (val.length >= len);
class CommentForm extends Component {
constructor(props) {
super(props);
this.state = {
isModalOpen: false,
isFormInValid: true
};
this.toggleModal = this.toggleModal.bind(this);
}
toggleModal() {
this.setState({
isModalOpen: !this.state.isModalOpen
})
}
handleSubmit(values) {
console.log("Current state is: " + JSON.stringify(values));
alert(JSON.stringify(values));
}
handleUpdate(form) {
this.setState({ isFormInValid: !form['$form'].valid });
}
render() {
return (
<>
<Button outline onClick={this.toggleModal}>
<span className="fa fa-pencil fa-lg"></span> Submit Comment
</Button>
<Modal isOpen={this.state.isModalOpen} toggle={this.toggleModal}>
<ModalHeader toggle={this.toggleModal}>Submit Comment</ModalHeader>
<ModalBody>
<LocalForm
onUpdate={(form) => this.handleUpdate(form)}
onSubmit={(values) => this.handleSubmit(values)}>
<Row className="form-group">
<Label htmlFor="author" md={12}>Your Name</Label>
<Col md={12}>
<Control.text model=".author" id="author" name="author"
placeholder="First Name" className="form-control"
validators={{ required, minLength: minLength(3), maxLength: maxLength(15) }} />
<Errors className="text-danger" model=".author" show="touched"
messages={{ required: 'Required ', minLength: 'Must be greater than 2 characters', maxLength: 'Must be 15 characters or less' }} />
</Col>
</Row>
<Row className="form-group">
<Col md={12}>
<Button type="submit" color="primary" disabled={this.state.isFormInValid}>Submit</Button>
</Col>
</Row>
</LocalForm>
</ModalBody>
</Modal>
</>
);
}
}