一、React表单控制
表单控制是React应用中常见的需求,React Hooks提供了两种方式来实现:受控组件和非受控组件。
1.1 受控组件
受控组件是将表单输入的值保存在组件的状态中。这样,表单数据就完全由React控制。
import React, { useState } from 'react';function ControlledInput() {const [value, setValue] = useState('');const handleChange = (e) => {setValue(e.target.value);};return <input type="text" value={value} onChange={handleChange} />;
}
1.2 非受控组件
非受控组件不使用React的状态来控制输入值,而是通过直接操作DOM来获取输入值。
import React, { useRef } from 'react';function UncontrolledInput() {const inputRef = useRef(null);const handleChange = () => {console.log(inputRef.current.value);};return <input type="text" ref={inputRef} onChange={handleChange} />;
}
二、React组件通信
组件通信是React应用中另一个重要的概念,它允许不同组件之间进行数据交换。
2.1 父子通信
父子组件之间的通信可以通过props实现。
function ParentComponent() {const name = 'Parent Name';return <ChildComponent name={name} />;
}function ChildComponent(props) {return <div>{props.name}</div>;
}
2.2 子传父通信
子组件可以通过回调函数将数据传递给父组件。
function ParentComponent() {const getMsg = (msg) => console.log(msg);return <ChildComponent onGetMsg={getMsg} />;
}function ChildComponent({ onGetMsg }) {const handleClick = () => {onGetMsg('this is son msg');};return <button onClick={handleClick}>Send Message</button>;
}
2.3 兄弟组件通信
兄弟组件通信通常通过提升状态到它们共同的父组件来实现。
function ParentComponent() {const [name, setName] = useState('');const handleAName = (name) => {setName(name);};return (<><AComponent onGetAName={handleAName} /><BComponent name={name} /></>);
}function AComponent({ onGetAName }) {const handleClick = () => {onGetAName('A Component Name');};return <button onClick={handleClick}>Send A Name</button>;
}function BComponent({ name }) {return <div>B Component Name: {name}</div>;
}
2.4 跨层组件通信
跨层组件通信可以通过React的Context API实现。
import React, { createContext, useContext, useState } from 'react';const MsgContext = createContext();function DeepChildComponent() {const msg = useContext(MsgContext);return <div>{msg}</div>;
}function IntermediateComponent() {return <DeepChildComponent />;
}function ParentComponent() {const msg = 'Message from Parent';return (<MsgContext.Provider value={msg}><IntermediateComponent /></MsgContext.Provider>);
}
三、React副作用管理:useEffect
useEffect
是React Hooks中用于处理副作用的函数,它可以在组件渲染后执行操作。
3.1 基本使用
import React, { useEffect, useState } from 'react';function ComponentWithEffect() {const [count, setCount] = useState(0);useEffect(() => {console.log('Component did mount and update');}, []); // 空依赖数组表示只在挂载时执行return (<div>Count: {count}</div>);
}
3.2 清除副作用
useEffect
可以返回一个清除副作用的函数,通常用于定时器或订阅的清理。
function ComponentWithCleanup() {useEffect(() => {const timer = setInterval(() => {console.log('Timer tick');}, 1000);// 清除副作用return () => clearInterval(timer);}, []); // 空依赖数组return <div>Component with cleanup</div>;
}
四、自定义Hook实现
自定义Hooks允许你封装可复用的逻辑。
4.1 创建自定义Hook
import { useState, useCallback } from 'react';function useToggle(defaultValue) {const [value, setValue] = useState(defaultValue);const toggle = useCallback(() => {setValue(prevState => !prevState);}, []);return [value, toggle];
}
4.2 使用自定义Hook
function App() {const [isOn, toggleOn] = useToggle(true);return (<div>{isOn ? 'Toggle is ON' : 'Toggle is OFF'}<button onClick={toggleOn}>Toggle</button></div>);
}
4.3 React Hooks使用规则
- 只能在函数组件中使用:Hooks让你在不编写类的情况下使用state和其他React特性。
- 只能在顶层使用:不要在循环、条件判断或嵌套函数中调用Hooks。
结语
通过本文的探索,我们了解到React Hooks提供了一种强大且灵活的方式来构建组件。无论是表单控制、组件通信,还是副作用管理,Hooks都提供了简洁的解决方案。自定义Hooks的引入更是让我们能够复用状态逻辑,编写更干净、更可维护的代码。掌握这些概念和技巧,将极大地提升你的React开发能力。