高阶组件
高阶组件是参数为组件,返回值为新组建的函数
createElement
cloneElement
基本使用
const nameRules = {required: true, message: "please input ur name"}
const passwordRules = {required: true, message: "please input ur pwd"}
@KFormCreate
class MyFormPage extends Component {
submit = () => {
console.log("submit");
const { getFieldsValue,validateFields } = this.props
validateFields((err,values)=>{
if(err){
console.log("err",err)
}else{
console.log("success",values)
}
})
}
render() {
console.log("props", this.props)
const { getFieldDecorator } = this.props
return (
<div>
<h3>MyFormPage</h3>
{getFieldDecorator('name', {rules:[nameRules]})(<input type="text" placeholder="please input ur name" />)}
<input type="password" placeholder="please input ur password" />
<button onClick={this.submit}>提交</button>
</div>
)
}
}
function KFormCreate(Cmp) {
return class extends Component {
constructor(props) {
super(props);
this.state = {};
this.options = {}
}
handleChange = e => {
let { value, name } = e.target;
this.setState({ [name]: value })
}
getFieldDecorator = (field, option) => {
this.options[field] = option
return InputCmp => {
return React.cloneElement(InputCmp, {
value: this.state[field] || "",
onChange: this.handleChange
})
}
}
getFieldsValue = () => {
return { ...this.state }
}
getFieldValue = (field) => {
return this.state[field]
}
validateFields=(cb)=>{
//校验错误信息
const errors = {}
const state = {...this.state}
for(let name in this.options){
if(this.state[name]===undefined){
errors[name] = 'error'
}
}
if(JSON.stringify(errors) === "{}"){
cb(undefined,state)
}else{
cb(errors,state)
}
}
render() {
return (
<div className="border">
<Cmp getFieldDecorator={this.getFieldDecorator}
getFieldsValue={this.getFieldsValue}
getFieldValue={this.getFieldValue}
validateFields={this.validateFields}
/>
</div>
)
}
}
}
弹窗类组件设计与实现
传送门
import {createPortal} from 'react-dom';
class Dialog extends Component {
constructor(props){
super(props)
const doc = window.document;
this.node = doc.createElement("div")
doc.body.appendChild(this.node)
}
componentWillUnmount(){
window.document.body.removeChild(this.node)
}
render(){
return createPortal(
<div className="dialog">
<h3>Dialog</h3>
{this.props.children}
</div>,this.node
)
}
}
class DialogPage extends Component {
constructor(props){
super(props);
this.state = {
showDialog: false
}
}
render(){
const {showDialog}= this.state;
return (
<div>
<h3>DialogPage</h3>
<button {()=>{this.setState({showDialog:!showDialog})}}>toggle</button>
{showDialog && (
<Dialog>
<p>我是一段文本</p>
</Dialog>
)}
</div>
)
}
}