React JS:可重用组件

韦伯曼

我已经用这样的结构创建了表单验证

var Signin = React.createClass({

    render: function() {

        return (
                <Form>
                    <Input type="text" name="email" labelName="Email" rules="isEmail" error:"Email not valid" />
                    <Input type="password" name="password" labelName="Password" rules="isLength:6" error:"Passowrd not valid"/>
                </Form>
        );
    }
});

因为,例如,“电子邮件”输入将在应用程序的不同部分使用,所以我避免每次都添加相同的属性(名称,类型,labelName,规则和错误)。所以我会创建这样的东西

var InputEmail = React.createClass({

    render: function () {

        return (
            <Input type="text" name="email" labelName="Email" rules="isEmail" error="Email not valid"/>
        )
    }
});

var InputPassword = React.createClass({

    render: function () {

        return (
            <Input type="password" name="password" labelName="Password" rules="isLength:6" error="Passwordnot valid"/>
        )
    }
});

因此登录组件应为

var Signin = React.createClass({

    render: function() {

        return (
                <Form>
                    <InputEmail />
                    <InputPassword />
                </Form>
        );
    }
});

但是这样,我会遇到两个错误:

  1. 我无法在Form中找到Input的props.name,因为InputEmail中没有。

  2. 在Input的呈现函数中,状态为null

如何创建可重用/继承的组件?我无法同时使用合成模式和mixins

我添加了完整的代码:表格

var Form = React.createClass({

    getInitialState: function () {
        return {
            isValid : false,
            isSubmitting: false
        }
    },

    componentWillMount: function(){
        this.model = {};
        this.inputs = {};
        this.registerInputs(this.props.children);

    },

    registerInputs: function(children){


        React.Children.forEach(children, function (child) {


            if (child.props.name) {


                child.props.attachToForm = this.attachToForm;

                child.props.detachFromForm = this.detachFromForm;

                child.props.validate = this.validate;
            }
            if (child.props.children) {
                this.registerInputs(child.props.children);
            }
        }.bind(this));
    },


    attachToForm: function (component) {
        this.inputs[component.props.name] = component;
        this.model[component.props.name] = component.state.value;
        this.validate(component);
    },

    detachFromForm: function (component) {
        delete this.inputs[component.props.name];
        delete this.model[component.props.name];
    },

    validate: function (component) {

        var isValid = true;
                // validation code
        component.setState({
            isValid: isValid,

        }, this.validateForm);

    },


    validateForm: function () {
        var formIsValid = true;

        var inputs = this.inputs;
        Object.keys(inputs).forEach(function (name) {
            if (!inputs[name].state.isValid) {
                formIsValid = false;
            }
        });

        this.setState({
            isValid: formIsValid
        });
    },

    updateModel: function (component) {
        Object.keys(this.inputs).forEach(function (name) {
            this.model[name] = this.inputs[name].state.value;
        }.bind(this));
    },

    submit: function (event) {
        event.preventDefault();

        this.setState({
            isSubmitting : true
        });

        this.updateModel();
        console.log(this.model);
    },

    render: function () {

        return (

            <form className="ui form" onSubmit={this.submit}>
                {this.props.children}
                <button className="ui button" type="submit" disabled={this.state.isSubmitting}>Accedi</button>
            </form>
        );
    }
});

输入

var Input = React.createClass({

    getInitialState: function(){
        return {
            value : this.props.value || "",
            isValid: true
        }
    },

    setValue: function (event) {

        this.setState({
            value: event.target.value
        }, function () {

            this.props.validate(this);

        }.bind(this));
    },

    componentWillMount: function () {

        if (this.props.required) {
            this.props.validations = this.props.validations ? this.props.validations + ',' : '';
            this.props.validations += 'isLength:1';
        }

                // ERROR: TypeError: this.props.attachToForm is not a function
        this.props.attachToForm(this);
    },

    componentWillUnmount: function () {
        this.props.detachFromForm(this);
    },


    render: function () {

        var className = "field";

        if(this.props.className){
            className +=  " " + this.props.className;
        }

        if(this.props.required){
            className += " required";
        }

        var Label;
        if(this.props.labelName){
            Label = (<label htmlFor={this.props.name}>{this.props.labelName}</label>);
        }

        var Error;
        if(!this.state.isValid){
            Error = (<div className="ui">{this.props.error || this.props.name + " not valid"}</div>);
        };


        return (
            <div className={className}>
                {Label}
                <input type={this.props.type || "text"} id={this.props.name} name={this.props.name} onChange={this.setValue} value={this.state.value} />
                {Error}
            </div>
        );

    }
});

有了这个作品

ReactDOM.render(
    <Form>
        <Input type="text" name="email" labelName="Email" rules="isEmail" error:"Email not valid"/>
    </Form>,
    document.getElementById('app')
);

这样,我得到:“ TypeError:this.props.attachToForm不是函数this.props.attachToForm(this);”

ReactDOM.render(
    <Form>
        <InputEmail/>
    </Form>,
    document.getElementById('app')
);

PS:我试图在jsfiddle上添加此代码,但得到“!TypeError:无法定义属性“ attachToForm”:对象不可扩展”

jsfiddle

温特维尔特

设置有2个主要问题:

  1. <Form>的设置方式如下:表格中的子项需要道具,否则它将无法正常工作。
  2. <InputEmail>包装是不完整的。它需要将所有道具传递到<Input>,包括向下传递的Form函数。

广告1:修正表单,以确保添加验证方法出现
此错误的原因是,您<Form>需要的子项都具有props.name。然后,通过将窗体的功能(包括attachToForm)添加到子窗体中,来进行注册。这是在方法中完成的registerInputs()

在原始变体中,<Input>组件具有道具,因此一切顺利。

在改编的变体中,包装器<InputEmail>不再具有prop,因此attachToForm()不会将and函数和其他函数添加到props中,并且在<Input>尝试调用该函数时会出现错误

解决此问题的最简单方法:在render函数中添加至少1个prop,然后在中进行检查registerInputs(),例如:

ReactDOM.render(
    <Form>
        <InputEmail initialValue={'[email protected]'}/>
    </Form>,
    document.getElementById('app')
);

然后在中registerInputs(),更改行:

if (child.props.name) {

到:

if (child.props.initialValue) {

2.扩展<InputEmail>包装器以传递函数,
最简单的方法是添加{...this.props},如下所示:

var InputEmail = React.createClass({

    render: function () {

        return (
            <Input {...this.props}
              type="text" name="email" labelName="Email" rules="isEmail" error="Email not valid"/>
        )
    }
});

这样,传递<Form><InputEmail>组件的功能(以及任何其他道具)将传递给<Input>组件。

PS:registerInputs()检查child.props.children的内部代码无法按预期运行:在调用该<InputEmail>组件时,该组件没有子代。顾名思义,它检查作为道具传递下来的孩子。而唯一通过的道具是initialValue

作为次要问题,我建议再进行2处更改:

  1. 在中registerInputs(),您可以直接修改道具。这通常不是一个好主意。更好的方法是制作道具副本,然后将形式方法添加到副本中。您可以React.Children.map用来执行此操作。在此处查看官方文档
  2. 在内部而不是对组件name="email"进行硬编码,更好的方法是使用,将这些的默认值放入props的默认值中,如官方文档中所述<Input><InputEmail>propTypes

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

什么是React JS可重用组件?

来自分类Dev

如何在react js的可重用组件中获取ref

来自分类Dev

在React Native中创建可重用组件?

来自分类Dev

如何制作可重用的React / MobX组件?

来自分类Dev

发送可重用的React组件的Redux操作

来自分类Dev

在 React 中使用 Typescript 使组件可重用

来自分类Dev

在Flux架构中创建具有内部事件的可重用React.js组件

来自分类Dev

React不是样式组件的样式可重用组件

来自分类Dev

在React中,应如何管理可重用List组件的状态?

来自分类Dev

如何在React中创建可重用的目录组件

来自分类Dev

如何在React中处理可重用组件?

来自分类Dev

TypeScript&React:可重用的通用动作/组件

来自分类Dev

具有Canvas的可重用react组件不会使用其props渲染canvas

来自分类Dev

React中的可重用搜索组件-CSS在文本溢出时失败

来自分类Dev

React-Hooks:如何创建具有动态内容的可重用数据表组件

来自分类Dev

React-Hooks:如何创建动态可重用数据表组件?

来自分类Dev

React-Hooks:如何创建可重用的数据表组件?

来自分类Dev

React可重用按钮组件-如何正确传递背景颜色道具?

来自分类Dev

高度可重用的react组件,无需更改任何代码,仅使用属性

来自分类Dev

在react中如何使用可重用组件作为React Component传递给react-router-dom Component属性?

来自分类Dev

在react中如何使用可重用组件作为React Component传递给react-router-dom Component属性?

来自分类Dev

如何制作可重用的vue js组件?

来自分类Dev

有没有办法通过道具传递动作?使用react-redux制作可重用组件

来自分类Dev

使用React和Typescript创建具有不可分配类型错误的可重用按钮组件

来自分类Dev

TypeScript React中的可重用布局组件:类型“ IntrinsicAttributes&IProps”上不存在属性“路径”

来自分类Dev

iOS可重用组件

来自分类Dev

可重用的d3.js组件和继承

来自分类Dev

如何重用具有不同标记的React组件?

来自分类Dev

React Native:不可重用组件的this.state状态

Related 相关文章

  1. 1

    什么是React JS可重用组件?

  2. 2

    如何在react js的可重用组件中获取ref

  3. 3

    在React Native中创建可重用组件?

  4. 4

    如何制作可重用的React / MobX组件?

  5. 5

    发送可重用的React组件的Redux操作

  6. 6

    在 React 中使用 Typescript 使组件可重用

  7. 7

    在Flux架构中创建具有内部事件的可重用React.js组件

  8. 8

    React不是样式组件的样式可重用组件

  9. 9

    在React中,应如何管理可重用List组件的状态?

  10. 10

    如何在React中创建可重用的目录组件

  11. 11

    如何在React中处理可重用组件?

  12. 12

    TypeScript&React:可重用的通用动作/组件

  13. 13

    具有Canvas的可重用react组件不会使用其props渲染canvas

  14. 14

    React中的可重用搜索组件-CSS在文本溢出时失败

  15. 15

    React-Hooks:如何创建具有动态内容的可重用数据表组件

  16. 16

    React-Hooks:如何创建动态可重用数据表组件?

  17. 17

    React-Hooks:如何创建可重用的数据表组件?

  18. 18

    React可重用按钮组件-如何正确传递背景颜色道具?

  19. 19

    高度可重用的react组件,无需更改任何代码,仅使用属性

  20. 20

    在react中如何使用可重用组件作为React Component传递给react-router-dom Component属性?

  21. 21

    在react中如何使用可重用组件作为React Component传递给react-router-dom Component属性?

  22. 22

    如何制作可重用的vue js组件?

  23. 23

    有没有办法通过道具传递动作?使用react-redux制作可重用组件

  24. 24

    使用React和Typescript创建具有不可分配类型错误的可重用按钮组件

  25. 25

    TypeScript React中的可重用布局组件:类型“ IntrinsicAttributes&IProps”上不存在属性“路径”

  26. 26

    iOS可重用组件

  27. 27

    可重用的d3.js组件和继承

  28. 28

    如何重用具有不同标记的React组件?

  29. 29

    React Native:不可重用组件的this.state状态

热门标签

归档