视图上某个状态发生了变化,所以视图要进行相应的更新
vue是编译时的行为
react时运行时的行为
useReducer //搜集所有操作某一个数据的方案
const {useReducer} from react;
const [count,dispatch] = useReducer(countReducer],0)
const countReducer(count,{type, payload}){
switch(case){
case 'Plus':
return count+playload;
case 'Minus':
return count-playload;
default:
return count;
}
}
return (
<div>
<h1>count<h1>
<button onClick={()=>{dispatch({type:'Plus',payload:2})}}></button>
<h1>count<h1>
<button onClick={()=>{dispatch({type:'Minus',payload:3})}}></button>
</div>
)
useEffect //与视图不相关的所有逻辑都是副作用 手动收集依赖
useEffect(()=>{},[])
第二个参数undefined,任何状态,都会执行回调函数 组件更新的声明周期
第二个参数不为数组,报警告
第二个参数[],回调函数只会函数组件调用时执行一次 conpomentDidMount
第二个参数有元素的数组,元素为状态 状态更新 回调重新执行一次 conpomentDidUpdate
useEffect(()=>{
// 页面卸载时 componentWillUnmount
// 这里只能返回一个函数 如果写async 返回的是promise
return ()=>{
// 清楚副作用 比如全局的函数 定时器
}
},[])
useState手写
const states=[]
const stateSetters = []
let stateIndex = 0;
function createState(initialState,stateIndex){
return states[stateIndex]? states[stateIndex]:initialState;
}
function createStateSetter(stateIndex){
return ((newState)=>{
if(typeof newState === 'fucntion'){
states[stateIndex] = newState(states[stateIndex])
}else{
states[stateIndex] = newState
}
render();
})
}
export function useState(initialState){
states[stateIndex] = createState(initialState,stateIndex)
if(!stateSetters[stateIndex]){
stateSetters.push = createStateSetter(stateIndex)
}
const _state = states[stateIndex]
const _setState = stateSetters[stateIndex]
stateIndex++;
return [_state,_setState ]
}
async function render()=>{
const App = (await import...)
stateIndex = 0;
effectIndex = 0;
root.render(<App/>)
}
//useReducer
export function useReducer(reducer,initialState){
const [state, setState] = useState(initialState)
function dispatch({type,payload}){
const newSate reducer(state, {type,payload})
setState(newState);
}
return [state.dispatch]
}
useEffect
fucntion useEffect(cb,depArr){
if(typeof cb!== 'function'){
throw new TypeError('callback must be a function')
}
if (depArr !== undefined && !Array.isArray(depArr){
throw new TypeError('depArr must be an array ')
}
const isChange = effectDepArr[effectIndex]?depArr.some((dep,index) => dep !== effectDepArr[effectIndex][index]):true;
if(isChange || depArr=== undefined){
cb();
}
effectDepArr[effectIndex] = depArr;
effectIndex++;
}