class Example extends React.Component {
复制代码
componentDidMount () {
fetch(`http://my.api/${this.props.name}`)
.then(...)
}
复制代码
componentDidUpdate (prevProps) {
if (this.props.name !== prevProps.name) {
fetch(`http://my.api/${this.props.name}`)
.then(...)
}
}
}
复制代码
fetchData () {
fetch(`http://my.api/${this.props.name}`)
.then(...)
}
复制代码
componentDidMount () {
this.fetchData()
}
componentDidUpdate (prevProps) {
if (this.props.name !== prevProps.name) { this.fetchData()
}
}
复制代码
import authenticateUser, { AuthenticationContext } from './auth'
复制代码
const App = () => (
<AuthenticationContext.Consumer>
{user =>
复制代码
user ? `${user} logged in` : 'not logged in'
复制代码
}
</AuthenticationContext.Consumer>
)
export default authenticateUser(App)
复制代码
<AuthenticationContext.Consumer>
{user => (
<LanguageContext.Consumer> {language => ( <StatusContext.Consumer> {status => ( ... )} </StatusContext.Consumer> )} </LanguageContext.Consumer>
)}
</AuthenticationContext.Consumer>
复制代码
function Example ({ name }) {
useEffect(() => {
fetch(`http://my.api/${this.props.name}`)
.then(...)
}, [ name ])
// ...
}
复制代码
const user = useContext(AuthenticationContext)
const language = useContext(LanguageContext)
const status = useContext(StatusContext)
复制代码
import React, { useState } from 'react';
import "./Welcome.scss";
function Welcome() {
const [data, setData] = useState({ hits: [{
objectID:"001",
url:"https://www.jd.com/",
title:"JD"
}] });
return (
<ul> {data.hits.map(item => ( <li key={item.objectID}> <a href={item.url}>{item.title}</a> </li> ))} </ul>
);
}
export default Welcome;
复制代码
function Welcome() {
const [data, setData] = useState({ hits: [{
objectID:"001",
url:"https://www.jd.com/",
title:"JD"
}] });
useEffect(async () => {
const result = await axios(
'http://localhost/api/v1/search?query=redux'
);
setData(result.data);
});
return (
<ul> {data.hits.map(item => ( <li key={item.objectID}> <a href={item.url}>{item.title}</a> </li> ))} </ul>
);
}
复制代码
function Welcome() {
const [data, setData] = useState({ hits: [{
objectID:"001",
url:"https://www.jd.com/",
title:"JD"
}] });
useEffect(async () => {
const result = await axios(
'http://localhost/api/v1/search?query=redux'
);
setData(result.data);
},[]);
return (
<ul> {data.hits.map(item => ( <li key={item.objectID}> <a href={item.url}>{item.title}</a> </li> ))} </ul>
);
}
复制代码
useEffect(() => {
const fetchData = async () => {
const result = await axios(
'http://localhost/api/v1/search?query=redux',
);
setData(result.data);
};
fetchData();
}, []);
复制代码
loading处理完成后,还须要处理错误,这里的逻辑是同样的,使用useState来建立一个新的state,而后在useEffect中特定的位置来更新这个state。因为咱们使用了async/await,可使用一个try-catch, 每次useEffect执行时,将会重置error;在出现错误的时候,将error置为true;在正常请求完成后,将error置为false。javascript
function Welcome() {
const [data, setData] = useState({ hits: [] });
const [query, setQuery] = useState('redux');
const [url, setUrl] = useState(
'http://localhost/api/v1/search?query=redux',
);
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
useEffect(() => {
const fetchData = async () => {
setIsError(false);
setIsLoading(true);
try {
const result = await axios(url);
setData(result.data);
} catch (error) {
setIsError(true);
}
setIsLoading(false);
};
fetchData();
}, [url]);
}
复制代码
方法名 | 用法 | 示例 | 思考 |
---|---|---|---|
useRef | 该方法返回一个可变的ref对象,其中.current属性初始化为传递的参数initialValue | import { useRef } from 'react'; const refContainer = useRef(initialValue) | useRef用于处理对React中的元素和组件的引用。咱们能够经过将ref属性传递给元素或组件来设置引用。 |
useReducer | 这个是useState的替代方案,其工做方式与Redux库相似 | import { useReducer } from 'react'; const [ state, dispatch ] = useReducer(reducer, initialArg, init) |
useReducer经常使用于处理复杂的状态逻辑。 |
useMemo | Memoization是一种优化技术,它缓存函数调用的结果,useMemo容许咱们计算一个值并将其记录下来 | import { useMemo } from 'react'; const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]) |
当咱们但愿避免从新执行费时的操做时,useMemo对于性能优化很是有用。 |
useCallback | 这个方法容许咱们传递一个内联回调函数和一组依赖项,并将返回回调函数的记忆版本。 | import { useCallback } from 'react'; const memoizedCallback = useCallback(() => {doSomething(a, b) }, [a, b]) | 当将回调函数传递给子组件时,useCallback很是有用。它的工做方式相似于useMemo,但用于回调函数。 |
useLayoutEffect | useLayoutEffect与useffect相同,但它只在全部的文档对象模型(Document Object Model,DOM)改变以后才触发。 | import { useLayoutEffect } from 'react'; useLayoutEffect(didUpdate) | useLayoutEffect可用于从DOM读取信息。(最好使用useffect,useLayoutEffect将阻止试图更新并减慢应用程序的渲染速度) |
useDebugValue | useDebugValue可用于在建立自定义Hook时在React DevTools中显示标签。 | import { useDebugValue } from 'react'; useDebugValue(value) | 在自定义Hook中可使用useDebugValue来显示Hook的当前状态,这样能够更容易地调试组件。 |
import { useInput } from 'react-hookedup'
function App () {
const { value, onChange } = useInput('')
return <input value={value} onChange={onChange} />
}
复制代码
import { useResource } from 'react-request-hook'
const [profile, getProfile] = useResource(id => ({ url: `/user/${id}`,
method: 'GET'
})
复制代码
import { useCurrentRoute, useNavigation } from 'react-navi'
const { views, url, data, status } = useCurrentRoute()
const { navigate } = useNavigation()
复制代码
import { useOnMount, useOnUnmount } from 'react-hookedup'
useOnMount(() => { ... })
useOnUnmount(() => { ... })
复制代码
import { useInterval, useTimeout } from 'react-hookedup'
useInterval(() => { ... }, 1000)
useTimeout(() => { ... }, 1000)
复制代码
import React from 'react'
import ReactDOM from 'react-dom'
复制代码
function useState (initialState) {
复制代码
let value = initialState
复制代码
function setState (nextValue) {
value = nextValue
ReactDOM.render(<MyName />,
document.getElementById('root'))
}
复制代码
return [ value, setState ]
}
复制代码
const [ name, setName ] = useState('')
复制代码
let value
function useState (initialState) {
复制代码
if (typeof value === 'undefined') value = initialState
复制代码
const [ name, setName ] = useState('')
const [ lastName, setLastName ] = useState('')
复制代码
function handleLastNameChange (evt) {
setLastName(evt.target.value)
}
复制代码
<h1>My name is: {name} {lastName}</h1>
复制代码
<input type="text" value={lastName} onChange=
{handleLastNameChange}
/>
复制代码
let value
复制代码
let values = []
let currentHook = 0
复制代码
if (typeof values[currentHook] === 'undefined')
values[currentHook] = initialState
复制代码
let hookIndex = currentHook
function setState (nextValue) {
values[hookIndex] = nextValue
ReactDOM.render(<MyName />,
document.getElementById('root'))
}
复制代码
return [ values[currentHook++], setState ]
复制代码
function Name () {
currentHook = 0
复制代码
const [ enableFirstName, setEnableFirstName ] = useState(false)
复制代码
function handleEnableChange (evt) {
setEnableFirstName(!enableFirstName)
}
复制代码
<input type="checkbox" value={enableFirstName} onChange= {handleEnableChange} />
复制代码
<h1>My name is: {enableFirstName ? name : ''} {lastName}
</h1>
复制代码
const [ name, setName ] = enableFirstName ? useState('')
: [ '', () => {} ]
复制代码
> npm install --save react-scripts@^2.1.8
复制代码
function UserInfo ({ username }) {
if (username) {
const info = useFetchUserInfo(username)
return <div>{info}</div>
}
return <div>Not logged in</div>
}
复制代码
function LoggedInUserInfo ({ username }) { const info = useFetchUserInfo(username)
return <div>{info}</div>
}
function UserInfo ({ username }) {
if (username) {
return <LoggedInUserInfo username={username} />
}
return <div>Not logged in</div>
}
复制代码
function OnlineUsers ({ users }) {
const [ userInfos, setUserInfos ] = useState([])
// ... fetch & keep userInfos up to date ...
return ( <div> {users.map(username => { const user = userInfos.find(u => u.username === username) return <UserInfo {...user} /> })} </div>
)
}
复制代码
function OnlineUsers ({ users }) {
return (
<div> {users.map(username => <UserInfo username={username} />)} </div>
)
}
function UserInfo ({ username }) {
const info = useFetchUserInfo(username)
// ... keep user info up to date ...
复制代码
type Hooks = {
memoizedState: any, // 指向当前渲染节点 Fiber
baseState: any, // 初始化 initialState, 已经每次 dispatch 以后 newState
baseUpdate: Update<any> | null,// 当前须要更新的 Update ,每次更新完以后,会赋值上 一个
update,方便 react 在渲染错误的边缘,数据回溯
queue: UpdateQueue<any> | null,// UpdateQueue 经过
next: Hook | null, // link 到下一个 hooks,经过 next 串联每一 hooks
}
type Effect = {
tag: HookEffectTag, // effectTag 标记当前 hook 做用在 life-cycles 的哪个阶段
create: () => mixed, // 初始化 callback
destroy: (() => mixed) | null, // 卸载 callback
deps: Array<mixed> | null,
next: Effect, // 同上
};
复制代码
class 组件 | Hooks 组件 |
---|---|
constructor | useState |
getDerivedStateFromProps | useState 里面 update 函数 |
shouldComponentUpdate | useMemo |
render | 函数自己 |
componentDidMount | useEffect |
componentDidUpdate | useEffect |
componentWillUnmount | useEffect 里面返回的函数 |
componentDidCatch | 无 |
getDerivedStateFromError | 无 |
class 组件 | Hooks 组件 |
---|---|
代码逻辑清晰(构造函数、componentDidMount等) | 须要配合注释和变量名 |
不容易内存泄漏 | 容易发生内存泄漏 |
一、官方文档css
二、useEffect 完整指南html
三、React 高阶组件java
四、简书 React Hooksreact