react中自定义hook--useReactive

自定义数据响应式hook – useReactive

react中,通常使用 useState 定义一个状态数据,如:

const [count, setCount] = useState(0)

可以使用 setCount 函数更新状态

setCount(1)
// 或
setCount((prevCount) => prevCount + 1)

如果想在组件引入的外部函数中使用 count 或者更新 count,就需要把 countsetCount 传入到这个外部函数中

import { increase } from './increaseCount'

export default function MyComponent() {
	const [count, setCount] = useState(0);
    
	return (
		<div>
			<button onClick={() => increase(count, setCount)}></button>
            <div>{ count }</div>
		</div>
	)
}
export function increase(count, setCount) {
	// 使用
    // todo...
    
    // 更新
    setCount((prevCount) => prevCount + 1)
    // 或者
    // setCount(count)
}

这样看来,更新 count 有点繁琐,有没有可能可以直接修改呢,就像普通对象那样

那必须有

通过自定义 hook 结合 Proxy 来实现

// useReactive.js

import { useMemo, useState } from 'react';

/**
 * 响应式数据
 * 和普通对象一样,直接修改
 * @param props
 */
export default function useReactive<T extends object>(props: T) {
  // useState的作用是触发react的自动更新
  const [state, setState] = useState<T>(props);

  return useMemo(() => {
    const proxyState = new Proxy(state, {
      set(target: T, p: string | symbol, value: any, receiver: any) {
        // 更新state,触发页面自动更新
        setState((prevState) => ({ ...prevState, [p]: value }));

        return Reflect.set(target, p, value, receiver);
      },
    });

    return proxyState;
  }, []);
}

然后就可以在组件中愉快的使用啦

function MyComponent() {
  const state = useReactive({
    count: 0,
  });

  return (
    <div>
      <button onClick={() => state.count++}>+1</button>
      <div>{state.count}</div>
    </div>
  );
}

// 或者,在外部函数中更新
function increaseCount(state: { count: number }) {
    state.count++
}

你可能感兴趣的:(前端,react)