reactjs学习手记(3)

React中事件的用法

概要

事件处理函数的使用

编写时间处理函数
组件    -->     React自有方法   render、componentWillUpdate、、、
        -->     用户自定义方法  handleClick、handleChange、handleMouseover
事件处理函数 可以接收一个event参数
绑定事件处理函数
onClick={this.handleClick}      //传入的包含所有方法的对象

触摸事件                //只会在移动端触发
onTouchCancel
onTouchEnd
onTouchMove
onTouchStart

键盘
onKeyDown
onKeyPress
OnKeyUp

剪切
onCopy
onCut
onPaste

表单
onChange
onInput
onSubmit

焦点
onFocus                 //得到焦点
onBlur                  //失去焦点

UI元素
onScroll

滚动
onWheel


鼠标
onClick
onContextMenu           //鼠标右键
onDoubleClick
onMouseDown
onMouseEnter
onMouseLeave
onMouseMove
onMouseOut
onMouseOver
onMouseUp


鼠标拖拽
onDrop                  //松开鼠标?
onDrag
onDragEnd
onDragEnter
onDragExit
onDragLeave
onDragOver
onDragStart

demo

<script src="./react.js"></script>
<script src="./JSXTransformer.js"></script>
<script type="text/jsx">
    var Hello = React.createClass({
        handleChange:function(event){
            console.log(event.target.value);
        },

        render: function(){
            return <div>
            <input onChange={this.handleChange} />
            </div>
        }
    });

    var instance = React.render(<Hello></Hello>,document.body);

</script>

事件对象的介绍

事件对象使用方式

handleChange:function(event){           //event是事件对象
    console.log(event.target.value);    //target就是事件对象的属性

}

不同事件对象介绍

通用
boolean bubbles                 //是否可以冒泡
boolean cancelable              //        取消
DOMEventTarget currentTarget    //
boolean defaultPrevented        //事件是否禁止默认行为
number eventPhase               //事件所处的阶段
boolean isTrusted               //事件是否可信  是否由用户触发
DOMEvent nativeEvent            //拿到原生的event
void preventDeafault()          //禁止默认行为
void stopPropagation()          //阻止冒泡
DOMEventTarget target           //
number timeStop                 //事件触发的时间
string type                     //事件触发的类型
剪切
DOMDataTransfer clipboardData   //
键盘事件
boolean altKey                  //是否按下了alt
Number charCode                 //字符编码
boolean ctrlKey                 //是否
function getModifierState(key)  //是否按下了辅助按键
String key                      //
Number keyCode                  //不是字符
String locale                   //本地化的
Number location                 //位置
boolean metaKey                 //win键 或 花键
boolean repeat                  //是否重复
boolean shiftKey                //
Number which                    //
焦点
DOMEventTarget relatedTarget    //两个焦点之间的关联
鼠标
boolean altKey
Number button
Number buttons
Number clientX
Number clientY
boolean ctrlKey
function getModifierState(key)
boolean metaKey
Number pageX
Number pageY
DOMEventTarget relatedTarget
Number screenX
Number screenY
boolean shiftKey
触摸
boolean altKey                     //
DOMTouchList changedTouches        //*
boolean ctrlKey                    //
function getModifierState(key)     //
boolean metaKey                    //
boolean shiftKey                   //
DOMTouchList targetTouches         //*
DOMTouchList touches               //*
UI元素
Number detail                   //
DOMAbstractView                 //
鼠标滚轮滚动
Number deltaMode                //
Number deltaX                   //
Number deltaY                   //
Number deltaZ                   //
demo

滚轮滚动改变颜色

<script src="./react.js"></script>
<script src="./JSXTransformer.js"></script>
<script type="text/jsx">
    var Hello = React.createClass({
        getInitialState:function(){
            return {
                backgroundColor:'#FFFFFF'
            }
        },
        handleWheel:function(event){
            var newColor = (parseInt(this.state.backgroundColor.substr(1),16) + event.deltaY * 997).toString(16);

            newColor = '#' + newColor.substr(newColor.length - 6).toUpperCase();

            this.setState({
                backgroundColor:newColor
            });
        },

        render: function(){
            console.log(this.state);
            return <div onWheel={this.handleWheel} style={this.state}>
            <p>Hello</p>
            </div>
        }
    });

    var instance = React.render(<Hello></Hello>,document.body);
</script>

密码示例

<script src="./react.js"></script>
<script src="./JSXTransformer.js"></script>
<script type="text/jsx">
    var Hello = React.createClass({
        getInitialState:function(){
            return {
                password:''
            }
        },
        handleKeyPress:function(event){
            this.setState({
                password:this.state.password + event.which
            });
            console.log("before update:");
            console.log(this.state);
        },
        componentDidUpdate:function(){
            console.log("after update:");
            console.log(this.state);
        },
        handleChange:function(event){
            event.value = '';
        },
        render: function(){
            return <div>
                <input  onKeyPress={this.handleKeyPress} onChange={this.handleChange}></input>
                <p style={{'display':this.state.password.indexOf('495051')>=0?'inline':'none'}}>You got it!</p>
            </div>;
        }
    });
    var instance = React.render(<Hello></Hello>,document.body);
</script>

事件和关联状态

事件和状态关联

handleChange:function(event){
    this.setState({inputText:event.target.value});
}

demo

记录鼠标移动坐标

<script src="./react.js"></script>
<script src="./JSXTransformer.js"></script>
<script type="text/jsx">
    var Hello = React.createClass({
        getInitialState:function(){
            return {
                x:0,
                y:0
            }
        },
        handleMouseMove:function(event){
            this.setState({
                x:event.clientX,
                y:event.clientY
            });
            console.log("before update:");
            console.log(this.state);
        },
        componentDidUpdate:function(){
            console.log("after update:");
            console.log(this.state);
        },
        render: function(){
            return <div onMouseMove={this.handleMouseMove} style={{height:'1000px',
              width:'700px'
            }}>{this.state.x + ' , ' + this.state.y}
            </div>;
        }
    });

    var instance = React.render(<Hello></Hello>,document.body);

</script>

组件协同使用介绍

什么是组件协同使用

组建的协同本质上市对组件的一宗组织、管理方式
目的:
    逻辑清晰
    代码模块化
    封装细节
    代码可复用

如何实现组件的协同使用

xy

组件嵌套

zujian

含义
组件嵌套实质上是父子关系
通信方式
父组件------属性------>子组件
父组件<--事件处理函数--子组件 //实质上是委托
优点
逻辑清晰:父子关系很好理解
代码模块化:每个模块对应一个功能,不同模块可以同步开发
封装细节:开发者只需要关注组件的功能,不用关心组件的实现细节
缺点
编写难度高:父子关系的具体实现需要经过深思熟虑,贸然编写将导致关系混乱、代码难以维护
无法掌握所有细节:使用者只知道组件用法,不知道细节,遇到问题难以修复
demo
<script src="./react.js"></script>
<script src="./JSXTransformer.js"></script>
<script type="text/jsx">
    var GenderSelect = React.createClass({
        render:function(){
            return <select onChange={this.props.handleSelect}>
                <option value="0">男</option>
                <option value="1">女</option>
            </select>
        }
    });
    var SignupForm = React.createClass({
        getInitialState:function(){
            return {
                name:'',
                password:'',
                gender:''
            }
        },
        handleChange:function(name,event){
            var newState = {};
            newState[name] = event.target.value;
            this.setState(newState);
        },
        handleSelect:function(event){
            this.setState({gender:event.target.value});
        },
        render: function(){
            console.log(this.state);
            return <form>
                <input type="text" placeholder="username..." onChange={this.handleChange.bind(this,'name')} />
                <input type="password" placeholder="password..." onChange={this.handleChange.bind(this,'password')} />
                <GenderSelect handleSelect={this.handleSelect}></GenderSelect>
            </form>;
        }
    });

    var instance = React.render(<SignupForm></SignupForm>,document.body);

</script>

Mixin编写和使用

this.handleClick = function(){  //Mixin
    $.ajax(...)
    ...
}
Mixin的含义
Mixin=一组方法
Mixin的目的是横向抽离出组件的相似代码
相似概念:面向切面编程、插件
var SetIntervalMixin = {
    componentWillMount:function(){
        this.intervals = [];
    },
    setInterval:function(){
        this.intervals.push(setInterval.apply(null,arguments));
    },
    componentWillUnmount:function(){
        this.intervals.map(clearInterval);
    }
};

var TickTock = React.createClass({
    mixins:[SetIntervalMixin]   //Use the mixin
    getInitialState:function(){
        return {seconds:0};
    },
})
优点:
代码复用:抽离出通用代码,减少开发成本,提高开发效率
即插即用:可以直接使用许多现有的Mixin来编写自己的组件
适应性强:改动一次代码,影响多个组件
缺点
编写难度高:Mixin可能被用在各种环境中,兼容多种环境就需要更多的逻辑和代码,通用的代价是提高复杂度
降低代码可读性:组件的优势在于将逻辑和见面直接结合在一起,Mixin本质山会分散逻辑,理解起来难度更大

React双向绑定Mixin

非Mixin

<script src="./react.js"></script>
<script src="./JSXTransformer.js"></script>
<script type="text/jsx">

    var BindingExample = React.createClass({
        getInitialState:function(){
            return {
                text:''
            };
        },
        handleChange:function(event){
            this.setState({text:event.target.value});
        },

        render: function(){
            console.log(this.state);
            return <div>
                <input type="text" placeholder="please input..." onChange={this.handleChange} />
                <p>{this.state.text}</p>
            </div>;
        }
    });

    var instance = React.render(<BindingExample></BindingExample>,document.body);

</script>

Mixin写法

<script src="./react.js"></script>
<script src="./JSXTransformer.js"></script>
<script type="text/jsx">
    var BindingMixin = {
        handleChange: function(key){
            var that = this;
            return function(event){
                var newState = {};
                newState[key] = event.target.value;
                that.setState(newState);
            }
        }
    }

    var BindingExample = React.createClass({
        mixins:[BindingMixin],
        getInitialState:function(){
            return {
                text:''
            };
        },

        render: function(){
            console.log(this.state);
            return <div>
                <input type="text" placeholder="please input..." onChange={this.handleChange('text')} />
                <p>{this.state.text}</p>
            </div>;
        }
    });

    var instance = React.render(<BindingExample></BindingExample>,document.body);

</script>

表单详解

不可控组件和可控组件

什么是不可控组件

状态存储组件数据
<input type="text" defaultValue="Hello World!" />   //数据写死在属性中,导致组件中数据和state中数据可能不再互相对应,组件中的数据对于整个组件来说不可控
var inputValue=???
var inputValue=React.findDOMNode(this.refs.input).value

什么是可控组件

<input type="text" defaultValue="{this.state.value}" />   
var inputValue=this.state.value

为什么组件要可控

组件可控的好处
    符合React的数据流
    数据存储在state中,便于使用
    便于对数据进行处理

实例演示

不可控demo

demo

<script src="./react.js"></script>
<script src="./JSXTransformer.js"></script>
<script type="text/jsx">
    /*var MyForm = React.createClass({
        render: function(){
            return <input type="text" defaultValue="Hello"/>
        }
    });
    var instance = React.render(<MyForm></MyForm>,document.body);
    */
    var MyForm = React.createClass({
        submitHandler:function(event){
            event.preventDefault();
            var helloTo = React.findDOMNode(this.refs.helloTo).value;
            alert(helloTo);
        },  

        render:function(){  
            return <form onSubmit={this.submitHandler}>
                <input type="text" ref="helloTo" defaultValue="Hello World!" />
                <br />
                <button type="submit">Speak</button>
            </form>;
        }
    });

    var instance = React.render(<MyForm></MyForm>,document.body);
</script>
可控demo
<script src="./react.js"></script>
<script src="./JSXTransformer.js"></script>
<script type="text/jsx">
    var MyForm = React.createClass({
        getInitialState:function(){
            return {
                helloTo:"Hello World!"
            };
        },
        handleChange:function(event){
            this.setState({
                helloTo:event.target.value
            });
        },
        submitHandler:function(event){
            event.preventDefault();
            alert(this.state.helloTo);

        },  
        render:function(){  
            return <form onSubmit={this.submitHandler}>
                <input type="text" value={this.state.helloTo} onChange={this.handleChange}/>
                <br />
                <button type="submit">Speak</button>
            </form>;
        }
    });

    var instance = React.render(<MyForm></MyForm>,document.body);
</script>

不同表单元素的使用

表单元素介绍

label       <label htmlFor="name">Name</label>      //不常用、可由placeholder替代
input       <input type="checkbox" value="A" checked = {this.state.checked} onChange={this.handleChange} />      //***
textarea    <textarea value={this.state.helloTo} onChange={this.handleChange} />
select      <select value={this.state.heloTo} onChange={this.handleChange}>
                <option value="1">一</option>
                <option value="2">二</option>
            </select>

实例演示

<script src="./react.js"></script>
<script src="./JSXTransformer.js"></script>
<script type="text/jsx">
    var MyForm = React.createClass({
        getInitialState:function(){
            return {
                username:"",
                gender:"man",
                checked:false
            };
        },
        handleChange:function(name,event){
            var that = this;
            return function(event){
                var newState = {};
                var a;
                if(name=='checked'){
                    if(this.props.checked){     //此处只能使用this.props.checked
                        newState[name] = false;
                    } else {
                        newState[name] = true;
                    }
                }else{
                    newState[name] = event.target.value;
                }

                that.setState(newState);
            }
        },
        submitHandler:function(event){
            event.preventDefault();
            if(this.state.checked)              //此处只能使用this.state.checked
            console.log(this.state);
            else
            console.log("please agree the license");
        },  
        render:function(){  
            return <form onSubmit={this.submitHandler}>
                <label htmlFor="username">input username...</label>
                <input id="username" type="text" value={this.state.username} onChange={this.handleChange('username')} />
                <br />
                <select value={this.state.gender} onChange={this.handleChange('gender')}>
                    <option value="man">nan</option>
                    <option value="woman">nv</option>
                </select>
                <br />
                <label htmlFor="checkbox">agree user license</label>
                <input id="checkbox" type="checkbox" checked={this.state.checked} onChange={this.handleChange('checked')} />
                <button type="submit">register</button>
            </form>
        }
    });

    var instance = React.render(<MyForm></MyForm>,document.body);
</script>

事件处理函数复用

为什么要复用事件处理函数

功能相同的函数,不好维护
    onChange={this.handleChange1}
    onChange={this.handleChange2}
    onChange={this.handleChange3}
    onChange={this.handleChange4}
    onChange={this.handleChange5}
    onChange={this.handleChange6}
更好的写法
    onChange={this.handleChange}    //并且由它处理函数细节

事件处理函数的两种复用方式

bind复用
handleChange:function(name,event){
    ...
}
{this.handleChange.bind(this,'input1')}
name复用
handleChange:function(event){
    var name = event.target.name;   //需要额外添加属性
}
{this.handleChange}

demo

bind复用
<script src="./react.js"></script>
<script src="./JSXTransformer.js"></script>
<script type="text/jsx">
    var MyForm = React.createClass({
        getInitialState:function(){
            return {
                username:"",
                gender:"man",
                checked:false
            };
        },
        handleChange:function(name,event){

            var newState = {};
            var a;

            newState[name] = name=="checked"?event.target.checked:event.target.value;

            this.setState(newState);

        },
        submitHandler:function(event){
            event.preventDefault();
            if(this.state.checked)              //此处只能使用this.state.checked
            console.log(this.state);
            else
            console.log("please agree the license");
        },  
        render:function(){  
            return <form onSubmit={this.submitHandler}>
                <label htmlFor="username">input username...</label>
                <input id="username" type="text" value={this.state.username} onChange={this.handleChange.bind(this,'username')} />
                <br />
                <select value={this.state.gender} onChange={this.handleChange.bind(this,'gender')}>
                    <option value="man">nan</option>
                    <option value="woman">nv</option>
                </select>
                <br />
                <label htmlFor="checkbox">agree user license</label>
                <input id="checkbox" type="checkbox" checked={this.state.checked} onChange={this.handleChange.bind(this,'checked')} />
                <button type="submit">register</button>
            </form>
        }
    });

    var instance = React.render(<MyForm></MyForm>,document.body);
</script>
name复用
<script src="./react.js"></script>
<script src="./JSXTransformer.js"></script>
<script type="text/jsx">
    var MyForm = React.createClass({
        getInitialState:function(){
            return {
                username:"",
                gender:"man",
                checked:true
            };
        },
        handleChange:function(event){
            var newState = {};
            console.log(event.target.checked);
            newState[event.target.name] = event.target.name=="checked"?event.target.checked:event.target.value;
            this.setState(newState);
        },
        submitHandler:function(event){
            event.preventDefault();
            if(this.state.checked)              //此处只能使用this.state.checked
            console.log(this.state);
            else
            console.log("please agree the license");
        },  
        render:function(){  
            return <form onSubmit={this.submitHandler}>
                <label htmlFor="username">input username...</label>
                <input name="username" id="username" type="text" value={this.state.username} onChange={this.handleChange} />
                <br />
                <select name="gender" value={this.state.gender} onChange={this.handleChange}>
                    <option value="man">nan</option>
                    <option value="woman">nv</option>
                </select>
                <br />
                <label htmlFor="checkbox">agree user license</label>
                <input name="checked" id="checkbox" type="checkbox" checked={this.state.checked} onChange={this.handleChange} />
                <button type="submit">register</button>
            </form>
        }
    });

    var instance = React.render(<MyForm></MyForm>,document.body);
</script>
函数复用???
<script src="./react.js"></script>
<script src="./JSXTransformer.js"></script>
<script type="text/jsx">
    var MyForm = React.createClass({
        getInitialState:function(){
            return {
                username:"",
                gender:"man",
                checked:false
            };
        },
        handleChange:function(name,event){
            var that = this;
            return function(event){
                var newState = {};
                var a;
                if(name=='checked'){
                    if(this.props.checked){     //此处只能使用this.props.checked
                        newState[name] = false;
                    } else {
                        newState[name] = true;
                    }
                }else{
                    newState[name] = event.target.value;
                }

                that.setState(newState);
            }
        },
        submitHandler:function(event){
            event.preventDefault();
            if(this.state.checked)              //此处只能使用this.state.checked
            console.log(this.state);
            else
            console.log("please agree the license");
        },  
        render:function(){  
            return <form onSubmit={this.submitHandler}>
                <label htmlFor="username">input username...</label>
                <input id="username" type="text" value={this.state.username} onChange={this.handleChange('username')} />
                <br />
                <select value={this.state.gender} onChange={this.handleChange('gender')}>
                    <option value="man">nan</option>
                    <option value="woman">nv</option>
                </select>
                <br />
                <label htmlFor="checkbox">agree user license</label>
                <input id="checkbox" type="checkbox" checked={this.state.checked} onChange={this.handleChange('checked')} />
                <button type="submit">register</button>
            </form>
        }
    });

    var instance = React.render(<MyForm></MyForm>,document.body);
</script>

表单组件自定义

为什么要自定义表单组件

内因
表单本省具备特殊性:样式统一、信息内聚、行为固定
外因
本质上是组件嵌套,组织和管理组件的一种方式

表单组件的两种定义方式

不可控的自定义组件

不推荐的方式

可控的自定义组件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值