本文用於記錄在使用andt相關組件時的採坑合集,挖掘一下組件的能力邊界javascript
getFieldsValue
getFieldValue
setFieldsValue
等
<FormItem
{...formItemLayout}
label='name'}
>
{getFieldDecorator('name', {})(
<Input /> )} </FormItem>
複製代碼
help
required
validateStatus
沒法自動生成。
2.2.0
以前,只有當表單域爲 Form.Item 的子元素時,纔會自動生成
help
required
validateStatus
,嵌套狀況須要自行設置。
Form.Item
子節點的值發生改變時觸發,能夠把對應的值轉存到 Redux store
@Form.create({
mapPropsToFields(props) {
// 使用上層組件的scope的值做爲表單的數據
const { scope } = props;
return {
nickname: Form.createFormField({
value: scope.nickname,
}),
phone: Form.createFormField({
value: scope.phone,
}),
address: Form.createFormField({
value: scope.address,
}),
agreement: Form.createFormField({
value: scope.agreement,
}),
};
},
onValuesChange(props, values) {
// 將表單的變化值回填到上層組件的scope中
props.onFormChange(values);
},
})
複製代碼
<FormItem
{...formItemLayout}
label='text'
extra={this.confirmNode()}
>
{getFieldDecorator('subscribe', {
initialValue: subscribe,
rules: [{
required: true,
message: ‘message’,
}],
})(
<Receiver subscribe={subscribe} onReceiverChange={this.onReceiverChange} /> )} </FormItem>
複製代碼
checkFormConfig = (rule, value, cb) => {
if (value.length === 0) {
cb('規則不能爲空');
}
}
...
<FormItem >
{getFieldDecorator('config', {
initialValue: 'init value',
rules: [{
validator: this.checkFormConfig,
}],
})(
<RuleConfig alarmConfig={alarmConfig} /> )} </FormItem>
複製代碼
提供受控屬性value
或其它與 valuePropName 的值同名的屬性。 提供onChange
事件或 trigger 的值同名的事件。 不能是函數式組件。
...
<FormItem>
</FormItem>
<Parent /> //不用在Parent外面包裝Item,在實際使用input的地方使用
class Parent extend PureComponent {
render () {
return <Child /> } } class Child extend PureComponent { render () { <FormItem> // 在實際的輸入上加Item { getFieldDecorator('continuous', { initialValue: continuous, rules: [ { required: true, message: 'please input u continuous', }, { validator: this.validate, }, ], })( // 絕對不用在這裏包裹div,否則就接收不到change <Select onChange={this.onChangeContinuous} > {continuousList} </Select> ) } </FormItem> } } 複製代碼
class MyComponent extends PureComponent {
constructor(){
super();
this.state = {
receiverList: [],// 受控屬性
}
}
onReceiverChange = receiverList => {
this.setState({ receiverList });
// 用於Form的回調
if (this.props.onChange) {
this.props.onChange(receiverList);
}
}
render() {
const receiverList = this.state.receiverList;
return (
<Input onChange={this.onReceiverChange} value={receiverList}/> ); } } 複製代碼
...
<Form>
<Form.Item> {getFieldDecorator('receiverList', { rules: [{ required: true, message: 'Please input name!', }], })( <Receiver receiverList /> )} </Form.Item> </Form> 複製代碼
<Form>
<Form.Item> {getFieldDecorator('receiverList', { rules: [{ required: true, message: 'Please input name!', }], })( //<div> 絕對不要在這裏加div,不然不能獲取select的change事件!!!!! <Select> <Option value=1>1</Option> </Select> )} </Form.Item> </Form>複製代碼
<Popconfirm
title={intl.find('alarm.attributes.sureToDelete')}
trigger="click"
onClick={this.onDelete(alarmId)}
>
<Icon type="delete" /> </Popconfirm>
複製代碼
<Popconfirm
title={intl.find('alarm.attributes.sureToDelete')}
trigger="click"
onConfirm={this.onDelete(alarmId)} // 使用正確的監聽函數
>
<Icon type="delete" onClick={evt => { evt.stopPropagation(); // 阻止事件冒泡 }} /> </Popconfirm>
複製代碼
<Popover
placement="bottomRight"
content={content}
trigger="click"
visible={this.state.visible}
onVisibleChange={this.handVisibleChange}
overlayClassName="xri-alarm-config-popover"
>
<i className={`${alarms.length > 0 && alarms[0].alarmObject.status === 'NORMAL' ? 'alarm-config-icon_useable' : 'alarm-config-icon'} feature-icon`} title={intl.find('charts.wrapHead.alarmConfig.title')} onClick={this.changVisible} /> </Popover>
content:
<Popconfirm title='title' onConfirm={this.onConfirm} onCancel={this.onCancel} okText='ok' cancelText='取消' visible={this.isShowPopConfirm(index)} getPopupContainer={this.getPopupContainer} onVisibleChange={this.handVisibleChange} overlayClassName="xri-alarm-popconfirm-sync" > <Tooltip title={intl.find('alarm.edit')} trigger="hover"> <span className="icon" onClick={this.checkSync(item, index)}> <Icon type="edit"/> </span> </Tooltip> </Popconfirm> 複製代碼
Function returning html node which will act as tooltip container. By default the tooltip attaches to the body. If you want to change the container, simply return a new element.
getPopupContainer
,更改父級關係後,你的visible事件就不會影響其餘組件了,可是要注意class, 由於層級發生變化,因此css的結構須要相應的該調整。
function beforeUpload(file, fileList) {
const isJPG = file.type === 'image/jpeg';
const isLt2M = file.size / 1024 / 1024 < 2;
const isGteMax = fileList.length > 3;
if (!isJPG) {
message.error('You can only upload JPG file!');
}
if (!isLt2M) {
message.error('Image must smaller than 2MB!');
}
if(isGteMax) {
message.error('Image count smaller than 4');
}
return isJPG && isLt2M && isGteMax;
}
...
<Upload
className="avatar-uploader"
name="avatar"
showUploadList={false}
action="//jsonplaceholder.typicode.com/posts/"
beforeUpload={beforeUpload}
multiple=true
onChange={this.handleChange}
>
<Button>upload</Button>
</Upload>
複製代碼
import { Upload, Button, Icon, message } from 'antd';
import reqwest from 'reqwest';
class Demo extends React.Component {
state = {
fileList: [],
uploading: false,
}
handleUpload = () => {
const { fileList } = this.state;
const formData = new FormData();
fileList.forEach((file) => {
formData.append('files[]', file);
});
this.setState({
uploading: true,
});
// You can use any AJAX library you like
reqwest({
url: '//jsonplaceholder.typicode.com/posts/',
method: 'post',
processData: false,
data: formData,
success: () => {
this.setState({
fileList: [],
uploading: false,
});
message.success('upload successfully.');
},
error: () => {
this.setState({
uploading: false,
});
message.error('upload failed.');
},
});
}
render() {
const { uploading } = this.state;
const props = {
action: '//jsonplaceholder.typicode.com/posts/',
onRemove: (file) => {
this.setState(({ fileList }) => {
const index = fileList.indexOf(file);
const newFileList = fileList.slice();
newFileList.splice(index, 1);
return {
fileList: newFileList,
};
});
},
beforeUpload: (file) => {
this.setState(({ fileList }) => ({
fileList: [...fileList, file],
}));
return false;
},
fileList: this.state.fileList,
};
return (
<div> <Upload {...props}> <Button> <Icon type="upload" /> Select File </Button> </Upload> <Button className="upload-demo-start" type="primary" onClick={this.handleUpload} disabled={this.state.fileList.length === 0} loading={uploading} > {uploading ? 'Uploading' : 'Start Upload' } </Button> </div> ); } } ReactDOM.render(<Demo />, mountNode); 複製代碼
/* eslint no-console:0 */
import React from 'react';
import ReactDOM from 'react-dom';
import Upload from 'rc-upload';
import axios from 'axios';
const uploadProps = {
action: '/upload.do',
multiple: false,
data: { a: 1, b: 2 },
headers: {
Authorization: '$prefix $token',
},
onStart(file) {
console.log('onStart', file, file.name);
},
onSuccess(ret, file) {
console.log('onSuccess', ret, file.name);
},
onError(err) {
console.log('onError', err);
},
onProgress({ percent }, file) {
console.log('onProgress', `${percent}%`, file.name);
},
customRequest({
action,
data,
file,
filename,
headers,
onError,
onProgress,
onSuccess,
withCredentials,
}) {
// EXAMPLE: post form-data with 'axios'
const formData = new FormData();
if (data) {
Object.keys(data).map(key => {
formData.append(key, data[key]);
});
}
formData.append(filename, file);
axios
.post(action, formData, {
withCredentials,
headers,
onUploadProgress: ({ total, loaded }) => {
onProgress({ percent: Math.round(loaded / total * 100).toFixed(2) }, file);
},
})
.then(({ data: response }) => {
onSuccess(response, file);
})
.catch(onError);
return {
abort() {
console.log('upload progress is aborted.');
},
};
},
};
const Test = () => {
return (
<div style={{ margin: 100, }} > <div> <Upload {...uploadProps}> <button>開始上傳</button> </Upload> </div> </div>
);
};
ReactDOM.render(<Test />, document.getElementById('__react-content'));複製代碼
目前總結了 Form,ToolTip, Upload的能力邊界,但願對你們有用~css