• React@16.x(14)context 举例 - Form 表单


    1,目标

    上篇文章说到,context 上下文一般用于第3方组件库,因为使用场景是需要多个组件之间相互配合实现一整套的逻辑。(高内聚的思想)

    所以利用上下文的特性简单封装一个表单,看看如何实现和使用。

    element-ui 中 Form 表单组件之间的联动,也是一个思想。它使用的 发布订阅模式 来逐层传递数据。

    2,实现

    整体目录:

    src/components/Form
    -- index.js
    -- context.js // 存放上下文数据。
    -- FormInput.js
    -- FormButton.js
    

    2.1,index.js

    import React, { Component } from "react";
    import PropTypes from "prop-types"; // 用于验证 props 类型
    import { Provider } from "./context";
    import FormInput from "./FormInput";
    import FormButton from "./FormButton";
    
    export default class Form extends Component {
        state = {
            formData: {},
            changeFormData: (name, value) => {
                this.setState({
                    formData: {
                        ...this.state.formData,
                        [name]: value,
                    },
                });
            },
            submit: () => {
                this.props.onSubmit?.(this.state.formData);
            },
        };
    
        static propTypes = {
            onSubmit: PropTypes.func,
        };
    
        render() {
            return <Provider value={this.state}>{this.props.children}</Provider>;
        }
    }
    
    // 赋值到 Form 组件上方便引用。
    Form.Input = FormInput;
    Form.Button = FormButton;
    

    2.2,context.js

    import React from "react";
    
    const ctx = React.createContext();
    export const { Provider, Consumer } = ctx;
    export default ctx;
    

    2.2,Form.Input

    注意 input.value 属性,因为 this.context.formData[this.props.name] 一开始是 undefined,所以得加一个默认值 '',否则 React 会认为是非受控组件而报错。

    import React, { Component } from "react";
    import PropTypes from "prop-types";
    import ctx from "./context";
    
    export default class FormInput extends Component {
        static contextType = ctx;
    
        static defaultProps = {
            type: "text",
        };
    
        static propTypes = {
            type: PropTypes.string.isRequired,
            name: PropTypes.string.isRequired,
        };
        render() {
            return (
                <div>
                    <input
                        type={this.props.type}
                        name={this.props.name}
                        value={this.context.formData[this.props.name] || ""}
                        onChange={(e) => {
                            this.context.changeFormData(this.props.name, e.target.value);
                        }}
                    ></input>
                </div>
            );
        }
    }
    

    2.3,Form.Button

    import React from "react";
    import { Consumer } from "./context.js";
    
    export default function FormButton(props) {
        return (
            <Consumer>
                {(ctx) => {
                    return <button onClick={() => ctx.submit()}>{props.children}</button>;
                }}
            </Consumer>
        );
    }
    

    3,使用

    import React, { Component } from "react";
    import Form from "./components/Form/index";
    
    export default class App extends Component {
        render() {
            return (
                <div>
                    <Form
                        onSubmit={(formData) => {
                            console.log(formData);
                        }}
                    >
                        <div>
                            <label>用户名</label>
                            <Form.Input name="id"></Form.Input>
                        </div>
                        <div>
                            <label>用户名</label>
                            <Form.Input name="pwd" type="password"></Form.Input>
                        </div>
                        <Form.Button>获取FormData</Form.Button>
                    </Form>
                </div>
            );
        }
    }
    

    最终,点击按钮就能获取到 formData更新后的数据。


    以上。

  • 相关阅读:
    SpringCloud: FeignClient原理解析
    124. 二叉树中的最大路径和
    基于协同过滤算法的电影推荐系统
    Springboot服装服装销售管理系统毕业设计-附源码221801
    【公司UI自动化学习】
    SylixOS UDP网络应用编程
    17.2、JavaWeb-简介、JDBC的缺点、入门使用、mybatis的使用、条件查询、mybatis的参数传递
    Python美化桌面—自制桌面宠物
    ORB-SLAM安装过程遇到问题记录整理
    Spring常见面试题
  • 原文地址:https://blog.csdn.net/qq_40147756/article/details/139129877