react 使用hooks

react hooks文檔html

λ yarn add react@16.7.0-alpha.2
λ yarn add react-dom@16.7.0-alpha.2

設置 state

import React, { useState } from "react";
const l = console.log;

function Test() {

  const [n, setN] = useState(0);
  const [info, setInfo] = useState({
    name: "ajanuw",
  });

  function handleAddN() {
    setN(n + 1);
  }
  function handleInputChange(e) {
    setInfo({
      ...info,
      name: e.target.value,
    });
  }

  return (
    <div>
      <p>test</p>
      <p>{n}</p>
      <button onClick={handleAddN}>click me</button>
      <hr />
      <input type="text" value={info.name} onChange={handleInputChange} />
    </div>
  );
}

useEffect 鉤子

它像是 componentDidMount, componentDidUpdate, and componentWillUnmount 這3個鉤子
他將在第一次渲染運行,狀態改變時運行,返回一個函數來作到 componentWillUnmount 裏面作的一些事情
能夠執行多個
第2個參數能夠監聽指定的數據更新才執行react

import React, { useState, useEffect } from "react";
const l = console.log;
function Test() {
  const [age, setAge] = useState(0);
  const [info, setInfo] = useState({
    name: "ajanuw",
  });

  useEffect(
    () => {
      document.title = `hello ${info.name}`;
      let timer = setTimeout(() => {
        document.title = `react app`;
      }, 2000);

      return () => {
        l("卸載");
        clearTimeout(timer);
      };
    },
    [info],
  );

  useEffect(
    () => {
      l("只有age狀態更新,才能執行");
    },
    [age],
  );

  function handleInputChange(e) {
    setInfo({
      ...info,
      name: e.target.value,
    });
  }

  return (
    <div>
      <input type="text" value={info.name} onChange={handleInputChange} />
    </div>
  );
}

編寫本身的 hooks

就相似編寫 高階組件和渲染組件差很少ios

function Test() {
  const [age, setAge] = useState(0);
  const ajanuw = useInput("ajanuw");
  const suou = useInput("suou");

  useEffect(
    () => {
      l("只有age狀態更新,才能執行");
    },
    [age],
  );

  return (
    <div>
      <input type="text" {...ajanuw} />
      <br />
      <input type="text" {...suou} />
    </div>
  );
}

function useInput(iv) {
  const [info, setInfo] = useState({
    name: iv,
  });

  useEffect(
    () => {
      document.title = `hello ${info.name}`;
      let timer = setTimeout(() => {
        document.title = `react app`;
      }, 2000);
      return () => {
        clearTimeout(timer);
      };
    },
    [info],
  );

  function handleInputChange(e) {
    setInfo({
      ...info,
      name: e.target.value,
    });
  }

  return {
    value: info.name,
    onChange: handleInputChange,
  };
}

useContext

獲取 Context 上下文axios

rx

const l = console.log;

function Test(props) {
  const btnRef = useRef();
  useEffect(() => {
    const click$ = fromEvent(btnRef.current, "click");
    click$
      .pipe(
        map(v => v.type),
        throttleTime(2000),
      )
      .subscribe(l);
    return () => {
      click$.unsubscribe();
    };
  });
  return (
    <>
      <button ref={btnRef}>click me</button>
    </>
  );
}

加載異步數據 更具體的文章

useEffect 傳入空數組能夠避免在組件更新時激活它,但僅用於組件的安裝數組

import React, { useState, useEffect } from "react";
import axios from "axios";
import Mock from "mockjs";

Mock.mock("/mock/a", "post", opt => {
  const body = JSON.parse(opt.body);
  return Mock.mock({
    code: body.p >= 3 ? 1 : 0,
    "data|2": [
      {
        "id|+1": 1,
        label: "@word",
      },
    ],
    // data: [],
  });
}).setup({
  timeout: 1200,
});

const l = console.log;

function Test(props) {
  const { status, list, getMore, loading, error } = useDataApi(
    0,
    [],
    "/mock/a",
  );

  return (
    <>
      {loading && <div>加載中</div>}
      {!!list.length && (
        <ul>
          <li>
            <button onClick={getMore}>加載更多</button>
          </li>
          {list.map((el, i) => (
            <li key={i}>{el.label}</li>
          ))}
        </ul>
      )}
      {error && <div>暫無數據</div>}
    </>
  );
}

function useDataApi(initStatus, initData, url) {
  const [status, setStatus] = useState(initStatus); // 0 ok, 1 notData, 2 loading
  const [p, setP] = useState(1);
  const [list, setList] = useState(initData);

  useEffect(
    () => {
      getList();
    },
    [p],
  );

  async function getList() {
    setStatus(2);
    let { code, data } = await axios.post(url, { p });
    if (code === 1) {
      setStatus(1);
    } else {
      setList(pdata => [...pdata, ...data]);
      setStatus(0);
    }
  }

  function getMore() {
    setP(pp => pp + 1);
  }

  return { status, list, getMore, loading: status === 2, error: status === 1 };
}

export default Test;
相關文章
相關標籤/搜索