Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react hooks 基础 #12

Open
fengyua5 opened this issue Oct 31, 2019 · 0 comments
Open

react hooks 基础 #12

fengyua5 opened this issue Oct 31, 2019 · 0 comments

Comments

@fengyua5
Copy link
Owner

fengyua5 commented Oct 31, 2019

React Hooks

1. useState

  • 参数类型:object、number、string、bool等等类型或者函数(只有在初始化的时候执行一次)
  • 返回值 [xx, setXx] (第一个值是存储的值,第二个值是改变值的方法(注意传入新的内存地址))
function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
    </>
  );
}

注意上述例子中setCount可以传入函数,函数的参数是最新的存储值,函数的返回值是要设置的值

2、useEffect(didMount、didUpdate)

  • 参数
    • 第一个参数是函数didUpdate,必填, 函数体中的代码会在render之后执行,此函数的返回函数会在组件写在之前执行(相当于原来的componentWillunmount中)
    • 第一个参数可填可不填,相当于在didMount、didUpdate执行
      1、如果不填相当于在在
      2、填[]didMount执行,didUpdate不执行
      3、如果传[xxx],didMount执行一次,当xxx发生变化的时候didUpdate会再执行
useEffect(
  () => {
    const subscription = props.source.subscribe();
    return () => {
      subscription.unsubscribe();
    };
  },
  [props.source],
);
> 

3、useContext

  • 参数 接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值

注意当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定

const DataState = React.createContext({});
 <DataState.Provider
        value={{
          recommendState,
          dispatch,
          doRecommendRef
        }}>
        <XXX />
  </DataState.Provider>
(xxx组件)
 const { recommendState, dispatch } = useContext(DataState)

4、useReducer

const [state, dispatch] = useReducer(reducer, initialArg, init);

使用方法和Redux类似

  • 例子
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();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
    </>
  );
}

在某些场景下,useReducer 会比 useState 更适用,例如 state 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等。并且,使用 useReducer 还能给那些会触发深更新的组件做性能优化,因为你可以向子组件传递 dispatch 而不是回调函数 。

5、useCallback

  • 参数 第一个是函数,第二个参数可以不传或者传数组(依赖项)
const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

当依赖项发生变化的时候,memoizedCallback会得到新的函数,useCallback(fn, deps) 相当于 useMemo(() => fn, deps)

5、useMemo

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

传入 useMemo 的函数会在渲染期间执行。请不要在这个函数内部执行与渲染无关的操作,诸如副作用这类的操作属于 useEffect 的适用范畴,而不是 useMemo。
如果没有提供依赖项数组,useMemo 在每次渲染时都会计算新的值

6、useRef

useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` 指向已挂载到 DOM 上的文本输入元素
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

注意:ref.current上可以保存一些值,相当于this的功能

  • 实例
function Timer() {
  const intervalRef = useRef();

  useEffect(() => {
    const id = setInterval(() => {
      // ...
    });
    intervalRef.current = id;
    return () => {
      clearInterval(intervalRef.current);
    };
  });

  // ...
}

7、useImperativeHandle

useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用 ref 这样的命令式代码。useImperativeHandle 应当与 forwardRef 一起使用

function FancyInput(props, ref) {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));
  return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);

官方Hooks API

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant