高阶组件

高阶组件是参数为组件,返回值为新组建的函数
createElement
cloneElement
基本使用

  1. const nameRules = {required: true, message: "please input ur name"}
  2. const passwordRules = {required: true, message: "please input ur pwd"}
  3. @KFormCreate
  4. class MyFormPage extends Component {
  5. submit = () => {
  6. console.log("submit");
  7. const { getFieldsValue,validateFields } = this.props
  8. validateFields((err,values)=>{
  9. if(err){
  10. console.log("err",err)
  11. }else{
  12. console.log("success",values)
  13. }
  14. })
  15. }
  16. render() {
  17. console.log("props", this.props)
  18. const { getFieldDecorator } = this.props
  19. return (
  20. <div>
  21. <h3>MyFormPage</h3>
  22. {getFieldDecorator('name', {rules:[nameRules]})(<input type="text" placeholder="please input ur name" />)}
  23. <input type="password" placeholder="please input ur password" />
  24. <button onClick={this.submit}>提交</button>
  25. </div>
  26. )
  27. }
  28. }
  29. function KFormCreate(Cmp) {
  30. return class extends Component {
  31. constructor(props) {
  32. super(props);
  33. this.state = {};
  34. this.options = {}
  35. }
  36. handleChange = e => {
  37. let { value, name } = e.target;
  38. this.setState({ [name]: value })
  39. }
  40. getFieldDecorator = (field, option) => {
  41. this.options[field] = option
  42. return InputCmp => {
  43. return React.cloneElement(InputCmp, {
  44. value: this.state[field] || "",
  45. onChange: this.handleChange
  46. })
  47. }
  48. }
  49. getFieldsValue = () => {
  50. return { ...this.state }
  51. }
  52. getFieldValue = (field) => {
  53. return this.state[field]
  54. }
  55. validateFields=(cb)=>{
  56. //校验错误信息
  57. const errors = {}
  58. const state = {...this.state}
  59. for(let name in this.options){
  60. if(this.state[name]===undefined){
  61. errors[name] = 'error'
  62. }
  63. }
  64. if(JSON.stringify(errors) === "{}"){
  65. cb(undefined,state)
  66. }else{
  67. cb(errors,state)
  68. }
  69. }
  70. render() {
  71. return (
  72. <div className="border">
  73. <Cmp getFieldDecorator={this.getFieldDecorator}
  74. getFieldsValue={this.getFieldsValue}
  75. getFieldValue={this.getFieldValue}
  76. validateFields={this.validateFields}
  77. />
  78. </div>
  79. )
  80. }
  81. }
  82. }

弹窗类组件设计与实现

传送门

  1. import {createPortal} from 'react-dom';
  2. class Dialog extends Component {
  3. constructor(props){
  4. super(props)
  5. const doc = window.document;
  6. this.node = doc.createElement("div")
  7. doc.body.appendChild(this.node)
  8. }
  9. componentWillUnmount(){
  10. window.document.body.removeChild(this.node)
  11. }
  12. render(){
  13. return createPortal(
  14. <div className="dialog">
  15. <h3>Dialog</h3>
  16. {this.props.children}
  17. </div>,this.node
  18. )
  19. }
  20. }
  21. class DialogPage extends Component {
  22. constructor(props){
  23. super(props);
  24. this.state = {
  25. showDialog: false
  26. }
  27. }
  28. render(){
  29. const {showDialog}= this.state;
  30. return (
  31. <div>
  32. <h3>DialogPage</h3>
  33. <button {()=>{this.setState({showDialog:!showDialog})}}>toggle</button>
  34. {showDialog && (
  35. <Dialog>
  36. <p>我是一段文本</p>
  37. </Dialog>
  38. )}
  39. </div>
  40. )
  41. }
  42. }