本文講的如何利用context,將多個元件串聯起來,實現乙個更大的聯合元件。最具有這個特性的就是表單元件,所以本文例子就是乙個表單元件。本文例子參考 ant design 。本次不講 context 知識,需要的話等到下一次分享。
明白自己所需要的內容後,我們建立基本**中的幾個元件,form , formitem ,input , 以及 button。
具體內容看**中的注釋
form
首先我們要知道 form 元件在聯合元件中的負責的內容
**如下
import react, from 'react';
import proptypes from 'prop-types';
import from './item';
import from './button';
import from './input';
export class form extends component;
static defaultprops = ,
};static childcontexttypes = ;
state = ,
change: 0,
};// 為什麼不將資料全部放在 state 裡面,在本文最後會講到
registerstate = ,
rules: {},
label: {},
};getchildcontext() = this.state;
const = this.registerstate;
return ,
};} submit() = this.props;
if (onsubmit) = this.registerstate;
object.keys(form).foreach(key =>
}// 如果校驗規則裡面有 校驗函式時候,使用它
if (rule.hasownproperty('validator'))
// 校驗不通過,向校驗結果陣列裡面增加,並且結束本次校驗
if (!res) );
return false;
}});
});if (validates.length > 0) ; message: $`);
});// 將錯誤資訊返回到 state 並且由 context 向下文傳遞內容,例如 formitem 收集到該資訊,就可以顯示出錯誤內容和樣式
this.setstate();
}// 最後觸發 onsubmit 引數,將錯誤資訊和資料返回
onsubmit(validates, this.registerstate.form);
}} reset() = this.registerstate;
const = this.props;
this.registerstate.form = object.keys(form).reduce((t, c) => , {});
// 因為值不在 state 中,需要重新整理一下state,完成值在 context 中的更新
this.change();
} //更新某乙個值
setfieldvalue(name, value)
// 值和規則都不在state中,需要借助次方法更新內容
change() );
} // 註冊引數,最後資料收集和規則校驗都是通過該方法向裡面新增的內容完成
register(name, itemrules) = this.props;
this.registerstate.form[name] = defaultvalues.hasownproperty(name) ? defaultvalues[name] : '';
this.registerstate.rules[name] = itemrules;
} else \` has repeat`);
}}
// 新增 欄位名稱,優化體驗
registerlabel(name, label)
render()
); // 這裡使用括號因為在 webstrom 下格式化**後的格式看起來更舒服。
}}// 將子元件加入到 form 中 表示關聯關係
form.item = item;
form.button = button;
form.input = input;
formitem
它的功能不多
**如下
import react, from 'react';
import proptypes from 'prop-types';
export class item extends component ;
static childcontexttypes = ;
static contexttypes = ;
// 防止重複覆蓋 name 的值
lock = false;
// 獲取到 包裹的輸入元件的 name值,如果在存在 form 中,則向 form 註冊name值相對的label值
setname(name) = this.context;
if (form)
} else
} getchildcontext() ,
};} render() = this.props;
const = this.context;
let classname = 'form-item';
let help = false;
if (form)
}return (
) : ''}
);}}
input
暫時演示輸入元件為 input ,後面可以按照該元件內容,繼續增加其他操作元件
該型別元件負責的東西很多
**如下
import react, from 'react';
import proptypes from 'prop-types';
export class input extends component
// 如果在 form 中,不在 formitem 中,提示一下,不在 formitem 中不影響最後的值
if (context.form && !context.formitem)
// 在 formitem 中,就要通知它自己是誰
if (context.formitem)
// 在 form 中,就向 form 註冊自己的 name 和 校驗規則
if (context.form)
} shouldcomponentupdate(nextprops) = this.context;
const = this.props;
// 當 有 onchange 事件 或者外部使用元件,強行更改了 input 值,就需要通知 form 更新值
if (form && this.changelock && form.data[name] !== nextprops.value)
return true;
} static proptypes = )),
type: proptypes.oneof(['text', 'tel', 'number', 'color', 'date']),
};static defaultprops = ;
static contexttypes = ;
onchange(e) = this.props;
const = this.context;
if (onchange) else
}} render() = this.props;
const = this.context;
if (form)
return (
);}}
button
負責內容很簡單
**如下
import react, from 'react';
import proptypes from 'prop-types';
export class button extends component = this.context;
// 該元件只能用於 form
if (!form)
} static proptypes = ;
static defaultprops = ;
static contexttypes = ;
onclick() = this.context;
const = this.props;
if (type === 'reset') else
} render()
);}}
首先先講明為何 不將label 和資料不放在state 裡面因為多個元件同時註冊時候,state更新來不及,會導致部分值初始化不成功,所以最後將值收集在 另外的 object 裡面,並且是直接賦值
看了上面幾個元件的**,應該有所明確,這些元件組合起來使用就是乙個大的元件。同時又可以單獨使用,知道該如何使用後,又可以按照規則,更新整個各個元件,而不會說,乙個巨大無比的單獨元件,無法拆分,累贅又複雜。通過聯合元件,可以達成很多奇妙的組合方式。上文的例子中,如果沒有 form 元件, 單獨的 forminput 加 input,這兩個組合起來,也可以是乙個單獨的驗證器。
react基礎語法(三)元件的建立和復合元件
doctype html html head meta charset utf 8 title title script src script script src script script src script head body div id div script type text babe...
聯合元件 2023年9月戶外元件評測結果出爐
由pvmagazine cea聯合開展的西安光伏室外試驗場的發電量實證9月最新結果公布,實證顯示,雙面元件每瓦發電量佔據明顯優勢。2019年9月的整體雙面元件發電量增長率平均為6.9 雙面發電量增益是指雙面元件的額外發電量,與所有單面產品的平均發電量相比。雙面元件的效能穩定地高於平均發電量,多晶矽元...
android構建復合元件
package andorid.j.awin import android.content.context import android.graphics.canvas import android.util.attributeset import android.view.view import ...