創建響應式數據
react:useState/useReducer
vue:ref/reactive
使用:
useState
const testState = useState(false)
const test = testState[0]
const setTest = testState[1]
因為返回的是一個數組,一般使用數組解構賦值
const [test,setTest] = useState(false)
//setState更新值不是實時的,react為提高性能可能會合並多個setState
useReducer
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
const [state, dispatch] = useReducer(reducer, initialState);
//取值:state.count
//修改值:dispatch({type: 'decrement'})
ref/reactive
const test = ref(false)//基本類型
const test2 = reactive({count:10})//引用類型
返回一個響應式代理對象
緩存
vue:computed
react:useMemo/useCallback
區分:都接受函數參數,computed
自動收集依賴,useMemo/useCallback
需手動指定
返回值
const a = ref(1)
const res = computed(()=>{
return a.value+1
})
//a的值變化后computed會重新計算
const a = useState(1)
const res = useMemo(()=>{
return a.value+1
},[a])
//a的值變化后useMemo會重新計算
const res2 = useMemo(()=>{
return a.value+1
},[])
//a的值變化后useMemo不會重新計算
返回函數
const a = ref(1)
const fun = computed(()=>{
return (addCount)=>{ return a.value+addCount}
})
const res = fun(10)
//a的值變化后computed會重新計算
const a = useState(1)
const fun = useCallback((addCount)=>{
return a.value+addCount
},[a])
const res = fun(10)
//a的值變化后useMemo會重新計算
副作用
vue:mounted/unmounted/...
(同vue生命周期)
react:useEffect
useEffect(()=>{
//...mounted時執行,dependency改變時執(類似beforeUpdate)
return ()=>{
//...unmounted時執行
}
},[dependency])
ref
vue:ref
react:useRef
ref取值為.value,useRef為.current,其他用法基本一致,數據更新都是實時的
組件多層級傳值
vue:provide/inject
react:createContext/useContext
暴露方法/屬性給父組件
vue:直接在setup返回即可
react:useImperativeHandle
(與 forwardRef 一起使用)
官網示例:
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);
//渲染 <FancyInput ref={inputRef} /> 的父組件可以調用 inputRef.current.focus()。