in<FormItem/>
You do not need to explicitly give <Input>
Why pass onChange for data binding?
Antd’s
<Form.Item label="Username name="username">// The onchange method is not shown. But the component can get props. OnChange to pass the modified value<Input />
</Form.Item>
Copy the code
The reason for this is that the FormItem clone replaces the old Element with a new Element using the React. CloneElement method, adding the onChange event passed to the props of the new Element. Source link
ForEach (eventName => {childProps[eventName] = (... args: any[]) => { mergedControl[eventName]? . (... args); children.props[eventName]? . (... args); }; }); childNode = (<MemoInput
value={mergedControl[props.valuePropName| | 'value']}
update={updateRef.current}
>// Call cloneElement to create a new element mounted on onChange instead of the original one. {cloneElement(children, childProps)}</MemoInput>
}
Copy the code
// Replace Element's source code
export function replaceElement(element: React.ReactNode, replacement: React.ReactNode, props: RenderProps,) :React.ReactNode {
if(! isValidElement(element))return replacement;
return React.cloneElement(
element,
typeof props === 'function' ? props(element.props || {}) : props,
);
}
export function cloneElement(element: React.ReactNode, props? : RenderProps) :React.ReactElement {
return replaceElement(element, element, props) as React.ReactElement;
}
Copy the code
Why add onChange to the new Element instead of mounting the onChange method on the props of the original Element
For example,
const onChange = () = > {};
const element = React.createElement('div', { style: {width: '20px'}},The '*')
element.props.onChange = onChange;
Copy the code
Trying to run the above methods causes an Object is not Extensible error.
Freeze (element.props) is called when ReactElement describes a JSX, making the props freeze and non-extensible.
ReactElement. Js source code
const ReactElement = function (type, key, ref, self, source, owner, props) {
const element = {
$$typeof: REACT_ELEMENT_TYPE,
type,
key,
ref,
props,
_owner: owner,
};
if (Object.freeze) {
// Freeze is not extensible
Object.freeze(element.props);
Object.freeze(element);
}
return element;
};
Copy the code
When customizing form controls, children need to use the data management capabilities of the FormItem. Children need to be separate, not an array
As in the following case, if the FormItem is an array, the custom component doesn’t get the onChange method passed in, so it has to be used separately.
<Form.Item name="name" >
<CustomInput/>// Custom components<div>new</div>
</Form.Item>
Copy the code
// Use it alone
<Form.Item name="name" >
<CustomInput/>// Custom components</Form.Item>
Copy the code
If children is an array, it will be assigned directly and will not be replaced by Clone.
if (Array.isArray(children) && hasName) {
childNode = children;
}
Copy the code
Douyin e-commerce hot internal push:
We are the r&d team of Bytedance and Douyin e-commerce business, mainly responsible for the r&d of core commercial products of bytesystem platforms (Douyin, Huoshan, Toutiao, Watermelon, etc.). Every line of your code affects hundreds of millions of consumers.
We have offices in Beijing, Shanghai, Hangzhou and Wuhan.
Recruiting front end engineer, client engineer, back end engineer, lots of HC.
Push the links: job.toutiao.com/s/eh6VNHL
E-mail: [email protected]