react hooks文档html
λ yarn add react@16.7.0-alpha.2 λ yarn add react-dom@16.7.0-alpha.2
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> ); }
它像是 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> ); }
就相似编写 高阶组件和渲染组件差很少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, }; }
获取 Context 上下文axios
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;