网易云开发日志 day5

见证你的成长。

(1)推荐榜单列表的鼠标事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
this.state = {
zHvr: fasle,
};
...
map(item, index) =>
...
className={classnames({recTopList: true, zHvr: showOper})}
onMouseOut={this.handleMouseleave}
...
<NavLink
to="/"
onMouseOver={this.handleMouseover}
>
{item}
</NavLink>

显然,这样做当鼠标在NavLink上时,会使数组渲染的列表都有zHvr,所以考虑增加控制变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
this.state = {
zHvr: false,
operIndex: 0,
};

map(item, index) =>
className={classnames({recTopList: true, zHvr: showOper && index === operIndex && top === operTopname})}
...
/*operIndex为触发鼠标事件的目标元素。行吧,这个代码废了,因为我slice了一下,就有多个列表可能有相同的index了,因此加上Topname(榜单名)控制*/
<NavLink
to="/"
onMouseOver={() => {this.handleMouseover(index)}}
>
{item}
</NavLink>

另外还有一些样式上的细节问题

(2)关于onmouseoveronmouseout事件

当子元素绝对定位,父元素相对定位。

在父元素上注册

(3)createStore的简单实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const createStore = (reducer) => {
let state;
let listeners = [];
/*listener为组件通过store.subscribe注册的监听函数*/

const getState = () => state;

const dispatch = (action) => {
state = reducer(state, action);
listeners.forEach(listener => listener());
};

const subscribe = (listener) => {
listeners.push(listener);
return () => {
listeners = listeners.filter(l => l !== listener);
}
};

dispatch({});
/*初始化state*/

return { getState, dispatch, subscribe };
};

reudecers类似于arr.reduce(callback, initValue),用reduce来理解combineReducers是最合理的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const combineReducers = (reducers) => {

return (state = {}, action) => {
return Object.keys(reducers).reduce((nextState, key) => {
nextState[key] = reducers[key](state[key], action);
return nextState;
}, {});
};
};

reducer = {
oneReducer,
secondReducer,
thirdReducer,
};

(4) redux-thunk的实现

1
2


(5) 封装一个用来提取对象的工具类

1
2
3
4
5
6
7
8
export function sliceObj(obj, keys) {
return keys.reduce((result, key) => {
if (obj.hasOwnProperty(key)) {
result[key] = obj[key];
}
return result;
}, {});
}
-------------要说再见啦感谢大佬的光临~-------------