写代码通用思路 - 积累
react 前后不一样才变化(包括作用域)的思想
背景
点击一个新增样式的按钮,就会往我的数据里:
const productInfo = {
ideaName: [{value: ''}],
title: [{value: ''}],
desc: [{value: ''}],
url: [{value: ''}],
nickname: [{value: ''}]
};
每个后面继续加一个{value, ''},比如,结果变成这样:
const productInfo = {
ideaName: [{value: ''}, {value: ''}],
title: [{value: ''}, {value: ''}],
desc: [{value: ''}, {value: ''}],
url: [{value: ''}, {value: ''}],
nickname: [{value: ''}, {value: ''}]
};
当数据被改变的时候,按理说,react的render方法会被触发,即状态改变,显示就改变。
我遇到的问题
我是这样写那个新增样式按钮触发的方法的:
addStyle() {
let thisInfo = this.get('productInfo');
Object.keys(thisInfo).map((item, index) => {
thisInfo[item].push({value: ''});
});
this.set('productInfo', thisInfo);
}
但是结果是,数据变了,但是没有重新跑render方法。
原因解释
first,一开始的thisInfo取到了productInfo(原地址的数据)
secondly,我push了新东西进thisInfo,其实就是改动了原地址的数据,意味着源数据其实就被我改变了
thirdly,所以,最后的this.set是没有任何写的必要的, 因为已经改动完了。
lastly,调用的this.set,react发现源数据和传的说要改的数据 值 是一模一样(虽然地址不一样,但是我用的那个react是用的_.isEqure,而不是===去判断的),所以就不走render了
就算是这样也是不行的:
addStyle() {
let thisInfo = this.get('productInfo');
Object.keys(thisInfo).map((item, index) => {
thisInfo[item].push({value: ''});
});
this.set('productInfo', {...thisInfo});
}
改进
addStyle() {
let thisInfo = this.get('productInfo');
let next = {};
Object.keys(thisInfo).map((item, index) => {
next[item] = [...thisInfo[item], {value: ''}];
});
this.set('productInfo', next);
},
或者
addStyle() {
let thisInfo = $.extend(true, {}, this.get('productInfo'));
Object.keys(thisInfo).map((item, index) => {
thisInfo[item].push({value: ''});
});
this.set('productInfo', {...thisInfo});
},
总结
1、react就是状态决定展现
2、react就是对比前后状态是否改变,而改变展现
3、一定不要去改原来的数据(不要在原来地址上改),而是要copy一份(新地址),再去改,可以用,但是不要改!
魔法数字
背景
checkbox性别,只有男女两个选项,我认为就不用放到配置里面了
but
value是变化的,现在规定男的value是1,女的value是2,但是这个1、2是魔法数字,以后可能会是3、 4或者其他啊
魔法数字 必须 单独声明
所以 必须放到配置里面
js的键值对
背景
哥哥让我把数据:
const AGE_LIST = [
{label: '<18', value: '1'},
{label: '18-24', value: '2'},
{label: '25-34', value: '3'},
{label: '35-44', value: '4'},
{label: '>44', value: '5'}
];
const INTEREST_LIST = [
{label: '影音娱乐', value: '1'},
{label: '软件应用', value: '2'},
{label: '资讯', value: '3'},
{label: '网络购物', value: '4'},
{label: '教育培训', value: '5'},
{label: '医疗健康', value: '6'},
{label: '游戏', value: '7'},
{label: '旅游出行', value: '8'},
{label: '汽车', value: '9'},
{label: '餐饮美食', value: '10'},
{label: '家电数码', value: '11'},
{label: '书籍阅读', value: '12'},
{label: '母婴亲子', value: '13'},
{label: '运动休闲', value: '14'},
{label: '金融财经', value: '15'},
{label: '求职创业', value: '16'},
{label: '房产家居', value: '17'},
{label: '个护美容', value: '18'},
{label: '生活服务', value: '19'},
{label: '其他', value: '20'}
];
const OS_LIST = [
{label: 'IOS', value: '1'},
{label: 'ANDROID', value: '2'},
{label: '其他', value: '3'}
];
转成 key => value
我犯得错误
我误以为要转成键值对数组
js哪里有键值对数组,php才有好不好!!!
键值对是object
键值对 key=>value 有时候叫map 映射 有时候叫hash
它也叫 PlainObject, 也是 object
const AGE_LIST = {'<18': 1, '18-24': 2, '25-34': 3, '35-44': 4, '>44': 5};
const INTEREST_LIST = {
'影音娱乐': 1,
'软件应用': 2,
'资讯': 3,
'网络购物': 4,
'教育培训': 5,
'医疗健康': 6,
'游戏': 7,
'旅游出行': 8,
'汽车': 9,
'餐饮美食': 10,
'家电数码': 11,
'书籍阅读': 12,
'母婴亲子': 13,
'运动休闲': 14,
'金融财经': 15,
'求职创业': 16,
'房产家居': 17,
'个护美容': 18,
'生活服务': 19,
'其他': 20
};
const OS_LIST = {'IOS': 1, 'ANDROID': 2, '其他': 3};
一个function一定要有return!
2016年7月02日记录
背景
利用react写项目
render(
datasource.map((item, index) => {
return (
<CheckBox
name={name}
label={item.label}
value={item.value}
onChange={onChange}
/>
);
})
我遇到的问题
这个是我封装的一个组件,是想返回一推checkbox数据
但是当我使用这个组件的时候,不显示效果
其实,就是因为render方法没有返回值!
我误以为,我写了return,其实那个是map方法的return
返回值是一堆零散的checkbox
改正
return (
<div className="check-list">
{
datasource.map((item, index) => {
//const checked = checkType === item.value;
return (
<CheckBox
//className=""
name={name}
label={item.label}
value={item.value}
onChange={onChange}
//checked={checked}
/>
);
})
}
</div>
);
需要注意的地方:
不能有零散的dom,要一个dom节点,所以我用了一个div包裹着map的返回值;
包装,保证数据类型
2016年4月21日记录
背景
document.addEventListener(types, handler,false);
addEventListener() 是事件注册方法,这是浏览器的方法。handler是观察者,当某个types(事件类型)被触发时就通知handler执行,这时候浏览器会传一个event(事件对象)给handler。
我遇到的问题
这个event是浏览器传给handler的,我想自己包装一个更完善的兼容的event对象。
这时,我写好了一个Event方法(构造函数)。
- 怎么把浏览器的event对象换成我自己写的?
可以知道,document.addEventListener(types, handler,false);的handler是函数类型,所以保证handler依旧是函数类型就行。
// 在保证数据类型的前提下, 这时浏览器传的event被我写的 function 接收到了。
document.addEventListener(types, function(event){
// 再把浏览器的event加工一下,变成我完善的event
event = new Event(event);
// 再执行要求执行的方法(通知观察者)
handler(event); // 其实到这里,代码是有点问题的,接下来会讲!你现在发现了吗?
},false);
关注输入输出
2016年4月21日记录
背景
发现上一部分最后那段代码的问题出在哪儿了吗?
我先不说。先问个其他问题:如果要你来实现addEventListener(),思路是啥?
首先,应该要有个收集器 去收集用户和浏览器的交互信息。然后,当某一个类型的事件(鼠标单击事件、键盘按下事件等等)被触发的时候就去通知所有观察这个事件的观察者,然后把包含事件信息的事件对象event传给观察者handler。handler执行。还要设定第三个参数来决定是事件捕获还是事件冒泡。
那通知观察者这一步:
假设是
var a = handler(event);
到这里,我们看回到上一部分最后的代码,我们是自己写了一个function,为的就是去改浏览器的event,然后addEventListener()中通知的观察者就变成我们自己写的那个function了。但是,这时候,addEventListener()中a就是undefined了。因为我们自己定义的function没有返回值呀!!!!!
我们只保证了输入一致,却没有保证输出一致!!
所以,上面的代码还得改进!
document.addEventListener(types, function(event){
event = new Event(event);
return handler(event);
},false);
改进下,一行代码搞定:
document.addEventListener(types, function(event){
return handler(new Event(event));
},false);