在React的世界里,Hooks是近年来的一大创新,它让函数组件也能拥有类组件的状态和生命周期等特性。掌握React Hooks,不仅能提升开发效率,还能实现各种动态组件效果。本文将为你带来20个实战案例,让你轻松玩转API,实现丰富的动态组件效果。
1. 使用useState实现计数器
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
2. 使用useEffect模拟组件生命周期
import React, { useEffect, useState } from 'react';
function LifeCycle() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('Component mounted');
}, []);
useEffect(() => {
console.log('Count changed', count);
}, [count]);
useEffect(() => {
return () => {
console.log('Component unmounted');
};
}, []);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
3. 使用useRef保持对DOM元素的引用
import React, { useRef } from 'react';
function RefExample() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>Focus Input</button>
</div>
);
}
4. 使用useContext实现组件间通信
import React, { useContext, useState } from 'react';
const ThemeContext = React.createContext();
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<DarkModeToggle />
<ThemeDisplay />
</ThemeContext.Provider>
);
}
function DarkModeToggle() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Toggle Theme
</button>
);
}
function ThemeDisplay() {
const { theme } = useContext(ThemeContext);
return <p>Current Theme: {theme}</p>;
}
5. 使用useCallback优化性能
import React, { useCallback, useState } from 'react';
function FilteredList({ items, filter }) {
const [filteredItems, setFilteredItems] = useState(items);
const handleFilterChange = useCallback((event) => {
setFilteredItems(items.filter((item) => item.includes(event.target.value)));
}, [items]);
return (
<div>
<input onChange={handleFilterChange} type="text" />
<ul>
{filteredItems.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</div>
);
}
6. 使用useMemo缓存计算结果
import React, { useMemo } from 'react';
function ExpensiveComponent({ data }) {
const result = useMemo(() => {
return data.map((item) => item.toUpperCase());
}, [data]);
return (
<div>
<ul>
{result.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</div>
);
}
7. 使用useReducer实现复杂状态管理
import React, { useReducer } from 'react';
const initialState = {
count: 0,
};
const reducer = (state, action) => {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
};
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
</div>
);
}
8. 使用useTransition优化长列表渲染
import React, { useTransition, useState } from 'react';
function LongList() {
const [query, setQuery] = useState('');
const [isPending, startTransition] = useTransition();
const filteredItems = query
? data.filter((item) => item.includes(query))
: data;
return (
<div>
<input
type="text"
value={query}
onChange={(e) => {
setQuery(e.target.value);
startTransition(() => {
// 长列表渲染
});
}}
/>
<ul>
{filteredItems.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</div>
);
}
9. 使用useLayoutEffect处理DOM更新
import React, { useLayoutEffect, useState } from 'react';
function LayoutEffect() {
const [count, setCount] = useState(0);
useLayoutEffect(() => {
const element = document.getElementById('layout-effect');
element.textContent = count;
}, [count]);
return (
<div>
<p id="layout-effect">Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
10. 使用useDebugValue方便调试
import React from 'react';
function DebugComponent() {
useDebugValue('This is a debug value');
return <p>Hello, world!</p>;
}
11. 使用useImperativeHandle控制子组件的引用
import React, { useRef, useImperativeHandle, forwardRef } from 'react';
const MyComponent = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
sayHello() {
alert('Hello!');
},
}));
return <p>Hello, world!</p>;
});
function ParentComponent() {
const childRef = useRef(null);
return (
<div>
<MyComponent ref={childRef} />
<button onClick={() => childRef.current.sayHello()}>
Say Hello
</button>
</div>
);
}
12. 使用useMemo优化组件渲染
import React, { useMemo } from 'react';
function ExpensiveComponent({ data }) {
const result = useMemo(() => {
return data.map((item) => item.toUpperCase());
}, [data]);
return (
<div>
<ul>
{result.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</div>
);
}
13. 使用useCallback优化事件处理函数
import React, { useCallback, useState } from 'react';
function FilteredList({ items, filter }) {
const [filteredItems, setFilteredItems] = useState(items);
const handleFilterChange = useCallback((event) => {
setFilteredItems(items.filter((item) => item.includes(event.target.value)));
}, [items]);
return (
<div>
<input onChange={handleFilterChange} type="text" />
<ul>
{filteredItems.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</div>
);
}
14. 使用useContext实现组件间通信
import React, { useContext, useState } from 'react';
const ThemeContext = React.createContext();
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<DarkModeToggle />
<ThemeDisplay />
</ThemeContext.Provider>
);
}
function DarkModeToggle() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Toggle Theme
</button>
);
}
function ThemeDisplay() {
const { theme } = useContext(ThemeContext);
return <p>Current Theme: {theme}</p>;
}
15. 使用useReducer实现复杂状态管理
import React, { useReducer } from 'react';
const initialState = {
count: 0,
};
const reducer = (state, action) => {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
};
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
</div>
);
}
16. 使用useLayoutEffect处理DOM更新
import React, { useLayoutEffect, useState } from 'react';
function LayoutEffect() {
const [count, setCount] = useState(0);
useLayoutEffect(() => {
const element = document.getElementById('layout-effect');
element.textContent = count;
}, [count]);
return (
<div>
<p id="layout-effect">Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
17. 使用useDebugValue方便调试
import React from 'react';
function DebugComponent() {
useDebugValue('This is a debug value');
return <p>Hello, world!</p>;
}
18. 使用useImperativeHandle控制子组件的引用
import React, { useRef, useImperativeHandle, forwardRef } from 'react';
const MyComponent = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
sayHello() {
alert('Hello!');
},
}));
return <p>Hello, world!</p>;
});
function ParentComponent() {
const childRef = useRef(null);
return (
<div>
<MyComponent ref={childRef} />
<button onClick={() => childRef.current.sayHello()}>
Say Hello
</button>
</div>
);
}
19. 使用useMemo优化组件渲染
import React, { useMemo } from 'react';
function ExpensiveComponent({ data }) {
const result = useMemo(() => {
return data.map((item) => item.toUpperCase());
}, [data]);
return (
<div>
<ul>
{result.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</div>
);
}
20. 使用useCallback优化事件处理函数
import React, { useCallback, useState } from 'react';
function FilteredList({ items, filter }) {
const [filteredItems, setFilteredItems] = useState(items);
const handleFilterChange = useCallback((event) => {
setFilteredItems(items.filter((item) => item.includes(event.target.value)));
}, [items]);
return (
<div>
<input onChange={handleFilterChange} type="text" />
<ul>
{filteredItems.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</div>
);
}
通过以上20个实战案例,相信你已经掌握了React Hooks的基本用法,并能轻松实现各种动态组件效果。在实际开发中,根据具体需求选择合适的Hooks,优化组件性能,提升用户体验。祝你在React的世界里畅游无阻!
