zoukankan      html  css  js  c++  java
  • 【总结】总结写了3个React页面后遇到的各种坑

    • 标签里用到<label for>的,for 要写成htmlFor
    • 标签里的class要写成className
    • 组件首字母一定要大写
    • 单标签最后一定要闭合
    • 如果html里要空格转义,&nbsp;注意不要漏了分号;
    • style要写成style={{clear: 'both',backgroundColor:'red','200px'}}
    • 组件里能用<button>的地方就不要用input type="button"了,否则写个value还要用{}
    • 标签里的ref属性的属性名不要出现中横杠比如message-content,如果有多个单词,直接写成驼峰形式
    • 把要改变的数据写进父组件的getInitialState的属性里,然后通过this.props.listArr传进去,表明初始状态是组件里listArr里的属性。
    • 如果将子组件改变的数据传递给父组件呢?可以在父组件里申明一个函数,里面传参data,然后在创建出子组件的对象的时候在属性上传入父组件的这个函数,然后在子组件里触发了某个事件的函数里,通过this.props.addItem()这样的方式调用父组件的函数,这个addItem就是父组件的函数,里面传参
    • 如果组件之间的通信超过的一层,传参就非常麻烦,需要用到react的一个插件叫PubSub订阅发布

    (1) 先导入库
    (2) 全局设置一个事件名称,子组件和父组件共用,比如var deleteItem = 'deleteItem';
    (3) 子组件,触发事件之后,发布事件

    
    //使用PubSub.publish(),第一个参数是公用的事件名称,第二个参数是你要传播的值
    deleteItemHandler:function(){
    	PubSub.publish(deleteItem, this.props.item);
    },
    

    (4) 父组件,是等组件全部渲染之后,因为组件还在内存中,虚拟DOM还没有渲染出来,没有正式出现在页面上时,是获取不到真是DOM的,所以在componentDidMount的函数里订阅一个从子组件发布出来的事件,在渲染完成后,会自动触发这个函数

    
    //使用PubSub.subscribe(),第一个参数是公用的事件名称,第二个参数是一个回调函数,可以是用箭头函数方式使它内部this指向组件对象,evName是事件对象,data就是子组件发布过来,这里接受到的data
    componentDidMount:function(){
    	PubSub.subscribe(deleteItem,(evName,data) =>{
    		var newArr = this.state.listArr.filter(function(item,index){
    			return item!= data;
    		});
    		this.setState({
    			listArr:newArr
    		});
    	});
    },
    
    • 这里顺便复习一下Arrayfilter()方法,参数里是个函数,参数是项和下标,return里写一个条件,所有符合条件的都会提取出来放到一个新的数组里,这里将数组里不等于传回来的这个data里的值的每一项都放到了newArr里,然后通过setState(),更新state里数组的值
    • 利用ReactCSSTransitionGroup来添加一些简单的动画效果,比如列表内容增加或者删除时可以有渐进渐出的效果。但是这个标签默认是span标签,使用在table或者options里提示警告,不能在tableoptions里嵌套span,所以可以通过它本身的component属性,比如component="div"直接将这个标签渲染为我们需要的标签即可。另外css里对应的动画时间要和这里标签里的时间对应
    var ListComponent = React.createClass({
    	render: function(){
    		return (
    			<ReactCSSTransitionGroup component="div" id="message-container" transitionName="messageContainer" transitionEnterTimeout={800} //这里定义渐进的时间
    			>
    
    			{ //这里放该组件的子级,也就意味写着这里面所有的内容的都会有动画效果,
    				this.props.mesArr.map(function(ele){
    					return <ItemComponent key={ele.time} {...ele} />
    				})
    			}
    
    			</ReactCSSTransitionGroup>
    		)
    	}
    });
    
    • 通过搜索框输入字符让显示区即时地筛选出搜索结果的效果。这里的难点是,如果直接通过onChange来获取打入的字符串来更新父组件的state里的数据,会造成数据返回不到原来的状态。所以思路可以是这样的,在父组件state里先创建一个空数组,每次当搜索框获取到焦点时,就把父组件当前的显示数据赋值给这个新建的数组,然后filter的时候是通过这个新数组里的数据进行筛选,而不是原来的数据,另外,当搜索框内容为空或者失去焦点时,再把视图的数据恢复到得到焦点时的状态即可。下面是可以实现的父组件中的代码:
    //在搜索框聚焦时,将当前state里的userList赋值给currentList,然后每次输入,筛选的对象都是currentList
    focusHandler:function(){
    	this.state.currentList = this.state.userList;
    },
    
    //在失去焦点时立刻将刚才存储的currentList赋值给userList,让视图再恢复到点击搜索框之前
    blurHandler:function(){
    	this.setState(function(){
    		return {
    			userList: this.state.currentList
    		}
    	});
    },
    
    //搜索功能
    searchUser:function(text){
    
    	//这里要将text进行判断,如果为空,就要让视图呈现刚聚焦时的状态,否则就进行筛选
    	if(text!=''){
    		var newText = text.toLowerCase();
    		var newArr = this.state.currentList.filter(function(item){ //每次点击通过保存的currentList来过滤
    			return item.username.toLowerCase().indexOf(newText) != -1;
    		});
    		this.setState(function(){
    			return {
    				userList: newArr
    			}
    		});
    	}else{
    		this.setState(function(){
    			return {
    				userList: this.state.currentList
    			}
    		});
    	}
    },
    
    • React-Router动画的结合使用
      除了两种技术的结合之外,有个很重要的地方不要忘记,就是要让每个单独的组件设置样式为position:absolute,否则在动画切换时会出现短暂组件叠加的的情况,用户体验非常差,但是绝对定位后,每个组件都在同一个地方渐入渐出了。
    //这里是react创建组件的ES6新写法,省略了function和内部的render,return。
    const MenuComponent = ({ children, location }) => (
    	<div> //这里是将组件Menu下控制的路由写在这里,每个路径用Link标签包起来,通过属性to来控制对应不同的路径
    		<div className="col-md-3 list-group">
    			<Link to="/statistic" className="list-group-item active">Website Statistic
    				Data</Link>
    			<Link to="/topics" className="list-group-item">Hot Topics</Link>
    			<Link to="/visits" className="list-group-item">Today's Visits</Link>
    			<Link to="/status" className="list-group-item">Server Status</Link>
    		</div>
    
    //这里把要对应的做成动画的区域用ReactCSSTransitionGroup包起来
    		<ReactCSSTransitionGroup className="col-md-9 pr clearfix"
    				component="div"
    				transitionName="content"
    				transitionEnterTimeout={500}
    				transitionLeaveTimeout={500}
    		>
    			{React.cloneElement(children, {key: location.pathname,className:"pa"})}
    		</ReactCSSTransitionGroup>
    	</div>
    )
    --------------------------------------------------------------
    //这里是render方法里的写法
    ReactDOM.render(
    	<Router> //根路由
    	//  "/"代表根路由,IndexRoute表示索引页,如果没有索引页可以作为默认显示的内容
    		<Route path="/" component={MenuComponent}>
    			<IndexRoute component={StatisticComponent} />
    			<Route default path="statistic" component={StatisticComponent} />
    			<Route path="topics" component={TopicComponent} />
    			<Route path="visits" component={GuestComponent} />
    			<Route path="status" component={StateComponent} />
    
    		</Route>
    	</Router>
    	,document.getElementById('container')
    );
    
    • 用ES6的箭头函数写组件
    const MenuComponent = ({ children, location }) => {
    
    //定义组件里的函数直接在组件里申明即可
    	const changeLink = (ev) => {
    		var parent = ev.target.parentNode;
    		var children = parent.children;
    		for(var i=0; i<children.length; i++){
    			children[i].classList.remove('active');
    		}
    		ev.target.classList.add('active');
    	};
    //这届写return (),里面写标签
    	return (
    		<div>
    			<div className="col-md-3 list-group" onClick={changeLink}> //这里不用再写this.changeLink了
    				<Link to="/statistic" className="list-group-item active">Website Statistic
    					Data
    				</Link>
    				<Link to="/topics" className="list-group-item">Hot Topics</Link>
    				<Link to="/visits" className="list-group-item">Today's Visits</Link>
    				<Link to="/status" className="list-group-item">Server Status</Link>
    			</div>
    
    			<ReactCSSTransitionGroup className="col-md-9 pr"
    component="div" transitionName="content" transitionEnterTimeout={500}	 transitionLeaveTimeout={500}
    			>
    			{React.cloneElement(children, {key: location.pathname, className: "pa"})}
    			</ReactCSSTransitionGroup>
    		</div>
    	);
    };
    
  • 相关阅读:
    BootStrap 之 CSS全局样式中的表格
    BootStrap 之 CSS全局样式中的图片
    BootStrap 之 CSS全局样式中的按钮
    Objective-C中的消息发送总结
    Android Studio精彩案例(七)《ToolBar使用详解<一>》
    How to Change Default Web ADI Upload Parameters for FlexField Import / Validation
    iOS中的颜色
    基于OGG的Oracle与Hadoop集群准实时同步介绍
    Android简易实战教程--第五十一话《使用Handler实现增加、减少、暂停计数》
    Android Studio精彩案例(六)《使用一个Demo涵盖补间动画所有知识》
  • 原文地址:https://www.cnblogs.com/bluefantasy728/p/5922021.html
Copyright © 2011-2022 走看看