useState
话不多说,上代码! 没错就是这么简单
//hook的索引,表示当前的index
let hookIndex=0;
//这里是一个数组,里面存放着我们所有的状态
let hookStates=[];
function render(vdom,container){
mount(vdom,container)
scheduleUpdate=()=>{
hookIndex=0;//在状态修改后调试更新的时候,索引重置为0
compareTwoVdom(container,vdom,vdom)
}
}
export function useState(initialState){
hookStates[hookIndex]=hookStates[hookIndex]||(typeof initialState==='function'?initialState():initialState);
let currentIndex=hookStates[hookIndex];
function setState(newState){
newState=typeof newState==='function'?newState(hookStates[currentIndex]):newState;
hookStates[currentIndex]=newState;
scheduleUpdate();//状态改变后重新更新应用
}
return [hookStates[hookIndex++],setState]
}
useCallback
话不多说,上代码! 没错就是这么简单
export function useCallback(callback,deps){
if(hookStates[hookIndex]){
const [lastCallback,lastDeps]=hookStates[hookIndex];
let same=deps.every((item,index)=>item===lastDeps[index]);
if(same){
hookIndex++;
return lastCallback;
}else{
hookStates[hookIndex++]=[callback,deps];
return callback
}
}else{
hookStates[hookIndex++]=[callback,deps]
return callback
}
}
useMemo
话不多说,上代码! 没错就是这么简单
export function useMemo(factory,deps){
if(hookStates[hookIndex]){
let [lastMemo,lastDeps]=hookStates[hookIndex];
let same=deps.every((item,index)=>item===lastDeps[index]);
if(same){
hookIndex++;
return lastMemo
}else{
let newMemo=factory();
hookStates[hookIndex++]=[newMemo,deps];
return newMemo
}
}else{
let newMemo=factory();
hookStates[hookIndex++]=[newMemo,deps]
return newMemo
}
}
memo
话不多说,上代码! 没错就是这么简单
function Memo(functionComponent){
return class extends PureComponent{
render(){
return functionComponent(this.props)
}
}
}
useReducer
话不多说,上代码! 没错就是这么简单
function useReducer(reducer,initialState){
hookStates[hookIndex]=hookStates[hookIndex]||initialState;
let currentIndex=hookIndex;
function dispatch(action){
hookStates[currentIndex]=reducer(hookStates[currentIndex],action);
scheduleUpdate();
}
return [hookStates[hookIndex++,dispatch]]
}
useContext
function createContext(initialValue) {
const context={Provider,Consumer}
function Provider(props) {
context._currentValue=context._currentValue||initialValue;
Object.assign(context._currentValue,props.value)
// Provider._value=props.value;
return props.children
}
function Consumer(props){
props.children(Provider._value)
}
return {Provider,Consumer}
}
function useContext(context) {
return context._currentValue
}
useEffect
function useEffect(callback,deps){
if(hookStates[hookIndex]){
let [functionDestory,lastDeps]=hookStates[hookIndex];
let same=deps.every((item,index)=>item===lastDeps[index]);
if(same){
hookIndex++;
}else{
functionDestory&&functionDestory();
//把回调放在了宏任务队列中,保证此回调函数不是同步执行,而是在页面渲染后执行
setTimeout(()=>{
let functionDestory = callback();
hookStates[hookIndex++] = [functionDestory,deps];
});
}
}else{
setTimeout(()=>{
let functionDestory=callback();
hookStates[hookIndex++]=[functionDestory,deps];
})
}
}
useLayoutEffect
function useLayoutEffect(callback,deps){
if(hookStates[hookIndex]){
let [functionDestory,lastDeps]=hookStates[hookIndex];
let same=deps.every((item,index)=>item===lastDeps[index]);
if(same){
hookIndex++;
}else{
functionDestory&&functionDestory();
//把回调放在了宏任务队列中
queueMicrotask(()=>{
let functionDestory = callback();
hookStates[hookIndex++] = [functionDestory,deps];
});
}
}else{
queueMicrotask(()=>{
let functionDestory=callback();
hookStates[hookIndex++]=[functionDestory,deps];
})
}
}
forwaredRef和useImperativeHandle
function forwardRef(FunctionComponent){
return class extends Component{
render(){
return FunctionComponent(this.props,this.ref)
}
}
}
function useImperativeHandle(ref,factory){
ref.current=factory();
}
useRequest向后台发送分页请求
function useRequest(url){
let limit=5;
let [offset,setOffset]=useState(0);
let [data,setData]=useState([]);
function loadMore(){
setData(null); //这里的null是为了在异步请求数据还没有回来的时候设置data=NULL去显示加载中的状态
fetch(`${url}?offset=${offset}&limit=${limit}`).then(res=>res.json()).then(newData=>{
setData([...data,...newData]);//data是上次的data,不是null,闭包机制
setOffset(offset+newData.length);
})
}
useEffect(()=>{
loadMore()
},[])
return [data,loadMore]
}