funny setup
Hello dear react developers, I'm so proud to announce that setup
is really a cool feature for code structure,I have used it to develop many basic components in my react app.
A very very simple component can be:
You can edit it on CodeSandbox:
With setup
, code can be more efficiently organized and reused, hope you can take a little time to understand it, and you will get huge profits in the development of react .
A form
Let us write a form with setup
import React from 'react';
import PropTypes from 'prop-types';
import { Form, Button, Radio } from 'antd';
import { useConcent } from 'concent';
import * as util from './_util';
const { Item: FormItem } = Form;
const { Group: RadioGroup, Button: RadioButton } = Radio;
const { getFieldTypeMaker } = util;
const cu = {
formItemLayout: (n) => {
return n.formLayout === 'horizontal'
? { labelCol: { span: 4 }, wrapperCol: { span: 14 } }
: null;
},
buttonItemLayout: (n) => {
return n.formLayout === 'horizontal'
? { wrapperCol: { span: 14, offset: 4 } }
: null;
},
};
const setup = ctx => {
ctx.initState({ formLayout: ctx.props.layout || 'horizontal', loading: false });
ctx.computed(cu);
ctx.on('cancelFormBtnLoading', () => {
ctx.setState({ loading: false });
});
const onLayoutChange = (e) => {
ctx.setState({ formLayout: e.target.value });
}
let renderLayoutControl = () => '';
if (ctx.props.dynamicLayout) {
renderLayoutControl = () => (
<FormItem label={ctx.props.layoutFieldLabel || 'Form Layout'} style={{ marginBottom: '10px' }}>
<RadioGroup value={ctx.state.formLayout} onChange={onLayoutChange}>
<RadioButton value="horizontal">Horizontal</RadioButton>
<RadioButton value="vertical">Vertical</RadioButton>
<RadioButton value="inline">Inline</RadioButton>
</RadioGroup>
</FormItem>
);
}
const onValuesChange = (changed) => {
console.log(changed);
if (ctx.props.onValuesChange) ctx.props.onValuesChange(changed);
};
const onFinish = (values) => {
console.log(values);
if (ctx.props.onFinish) {
ctx.props.onFinish(values);
ctx.setState({ loading: true });
}
};
const UIFields = ctx.props.fields.map((f, idx) => {
const { type, options } = f;
const makeFn = getFieldTypeMaker(type);
return makeFn(options);
});
const resetBtn = ctx.props.resetBtn;
let UIResetBtn = '';
if (resetBtn !== undefined) {
const onReset = () => ctx.extra.form.resetFields();
const btnLabel = typeof resetBtn !== 'string' ? 'Reset' : resetBtn;
UIResetBtn = (
<Button htmlType="button" onClick={onReset}>
{btnLabel}
</Button>
);
}
let UIFillBtn = '';
const { fillBtn, fillValues } = ctx.props;
if (fillBtn !== undefined) {
const onFill = () => {
if (!fillValues) {
return alert('请设置欲填充的默认值');
}
ctx.extra.form.setFieldsValue(fillValues);
};
const fillBtnLabel = typeof fillBtn !== 'string' ? 'Fill form' : fillBtn;
UIFillBtn = (
<Button htmlType="button" onClick={onFill}>
{fillBtnLabel}
</Button>
);
}
return {
renderLayoutControl,
UIFields,
UIResetBtn,
UIFillBtn,
onValuesChange,
onFinish,
}
}
/**@typedef {import('types/store').CtxDeS<{},
* {formLayout:string},
* import('concent').SettingsType<typeof setup>,
* import('concent').ComputedValType<typeof cu>
* >} Ctx */
/**
* @param {object} props
* @param {Array<FieldInput | FieldInputGroup>} props.fields - 表单字段描述对象
* @param {(changedValues:any)=>void} [props.onValuesChange] - 字段值改变时的回调
* @param {(values:any)=>void} [props.onFinish] - 提交表单时的回调
* @param {'horizontal'|'vertical'|'inline'} [props.layout='horizontal'] - 布局模式(水平、垂直、行内)
* @param {boolean} [props.dynamicLayout=false] - 是否动态布局
* @param {string} [props.layoutFieldLabel='Form Layout'] - 布局字段文案
* @param {string} [props.submitBtnLabel='Submit'] - 提交按钮的文案
* @param {boolean | string} [props.resetBtn=false] - 是否需要重置按钮,传递string表示重新默认文案
* @param {boolean | string} [props.fillBtn=false] - 是否需要填充表单按钮,传递string表示重新默认文案
* @param {object} [props.fillValues] - 设置需要填充的默认值
*/
const EasyForm = (props) => {
const [form] = Form.useForm();
/**@type Ctx */
const ctx = useConcent({ setup, props, extra: { form } });
const {
state: { formLayout, loading },
refComputed: { formItemLayout, buttonItemLayout },
settings: { renderLayoutControl, UIFields, UIResetBtn, UIFillBtn, onValuesChange, onFinish }
} = ctx;
return (
<div>
<Form
{...formItemLayout}
layout={formLayout}
form={form}
onFinish={onFinish}
initialValues={{
layout: formLayout,
}}
onValuesChange={onValuesChange}
>
{renderLayoutControl()}
{UIFields}
<Form.Item {...buttonItemLayout}>
<Button type="primary" htmlType="submit" loading={loading}>{props.submitBtnLabel || 'Submit'}</Button>
{UIResetBtn}
{UIFillBtn}
</Form.Item>
</Form>
</div>
);
}
EasyForm.propTypes = {
fields: PropTypes.array.isRequired,
}
export default React.memo(EasyForm);
here is the online form example
What is concent
concent is a build-in dependency collection, predictable、zero-cost-use、progressive、high performance's react develop framework.
❤ know more about concent ^_^
Edit js project on CodeSandbox
Edit ts project on CodeSandbox
If you have any questions about concent, you can post issues in git repo.
Top comments (0)