做的好的h游戏下载网站,wordpress去除主题加密页脚,个人网站建设详细教程,公司网站可以分两个域名做吗React基础学习-Day02
1.受控表单绑定
在 React 中#xff0c;受控表单#xff08;controlled form#xff09;是一种通过 React 组件状态#xff08;state#xff09;来管理表单元素值的方式。使用受控表单#xff0c;可以将表单元素的值与 React 组件的状态保持同步受控表单controlled form是一种通过 React 组件状态state来管理表单元素值的方式。使用受控表单可以将表单元素的值与 React 组件的状态保持同步从而实现对表单数据的完全控制和管理。
如何创建受控表单
1. 输入框Input
使用 input 元素作为例子展示如何创建一个受控输入框
import React, { useState } from react;const ControlledFormExample () {// 定义一个状态变量来存储输入框的值const [inputValue, setInputValue] useState();// 处理输入框值变化的函数const handleInputChange (event) {setInputValue(event.target.value); // 更新状态变量的值};// 提交表单时处理函数const handleSubmit (event) {event.preventDefault(); // 阻止表单默认提交行为alert(Submitted value: ${inputValue}); // 弹出输入框的当前值};return (form onSubmit{handleSubmit}labelInput:inputtypetextvalue{inputValue} // 将输入框的值与状态变量绑定onChange{handleInputChange} // 处理输入框值变化的函数//labelbutton typesubmitSubmit/button/form);
};export default ControlledFormExample;2. 复选框Checkbox
对于复选框需要注意初始状态和处理函数的变化
import React, { useState } from react;const CheckboxExample () {// 定义一个状态变量来存储复选框的选中状态const [isChecked, setIsChecked] useState(false);// 处理复选框状态变化的函数const handleCheckboxChange (event) {setIsChecked(event.target.checked); // 更新状态变量的值};// 提交表单时处理函数const handleSubmit (event) {event.preventDefault(); // 阻止表单默认提交行为alert(Checkbox checked: ${isChecked}); // 弹出复选框的当前选中状态};return (form onSubmit{handleSubmit}labelCheckbox:inputtypecheckboxchecked{isChecked} // 将复选框的选中状态与状态变量绑定onChange{handleCheckboxChange} // 处理复选框状态变化的函数//labelbutton typesubmitSubmit/button/form);
};export default CheckboxExample;3. 下拉菜单Select
对于 select 元素需要注意选项列表的处理和初始选中值
import React, { useState } from react;const SelectExample () {// 定义一个状态变量来存储选择框的当前选中值const [selectedValue, setSelectedValue] useState(option1);// 处理选择框选项变化的函数const handleSelectChange (event) {setSelectedValue(event.target.value); // 更新状态变量的值};// 提交表单时处理函数const handleSubmit (event) {event.preventDefault(); // 阻止表单默认提交行为alert(Selected value: ${selectedValue}); // 弹出选择框的当前选中值};return (form onSubmit{handleSubmit}labelSelect:select value{selectedValue} onChange{handleSelectChange}option valueoption1Option 1/optionoption valueoption2Option 2/optionoption valueoption3Option 3/option/select/labelbutton typesubmitSubmit/button/form);
};export default SelectExample;特点和优势
完全控制: 受控表单使得所有表单元素的值都由 React 组件状态管理可以通过状态更新函数精确控制和验证输入。一致性和可预测性: 因为状态直接驱动表单元素的值所以可以确保表单的行为一致和可预测。验证和处理: 可以轻松实现输入验证、条件渲染和复杂的表单逻辑例如禁用按钮直到所有必填字段都填写完毕。
通过使用受控表单React 组件能够更加灵活和可控地处理用户输入提高了应用的可维护性和用户体验。
2.React中如何获取DOM
在 React 中获取 DOM 元素通常是通过 Refs引用来实现的。Refs 提供了一种直接访问在 render 方法中创建的 DOM 节点或 React 元素的方式。这种访问方式是为了避免直接操作 DOM符合 React 的声明式和组件化的设计理念。
使用 Refs 获取 DOM
1. 创建 Refs
在函数式组件中可以使用 useRef 钩子来创建 Ref 对象
import React, { useRef } from react;const MyComponent () {// 创建一个 Ref 对象const myRef useRef(null);// 在 useEffect 中操作 RefuseEffect(() {console.log(myRef.current); // 输出 Ref 对象的当前值关联的 DOM 节点}, []);return (div ref{myRef}{/* 这里是组件内容 */}/div);
};export default MyComponent;2. 访问 DOM 节点
通过 ref.current 属性可以访问到 Ref 对象关联的 DOM 节点。需要注意的是Ref 对象在组件的整个生命周期中保持不变但 ref.current 的值会随着组件的渲染和卸载而变化。
3. 类组件中的 Refs
在类组件中Refs 的创建和访问稍有不同
import React, { Component } from react;class MyComponent extends Component {constructor(props) {super(props);// 创建一个 Ref 对象this.myRef React.createRef();}componentDidMount() {console.log(this.myRef.current); // 输出 Ref 对象的当前值关联的 DOM 节点}render() {return (div ref{this.myRef}{/* 这里是组件内容 */}/div);}
}export default MyComponent;在类组件中通过 React.createRef() 方法创建 Ref 对象并在 componentDidMount 生命周期中访问 this.myRef.current 获取 DOM 节点。
使用场景
直接操作 DOM: 当需要在 React 中进行 DOM 操作时例如测量元素尺寸、动画操作等可以使用 Refs 来获取并操作 DOM 元素。集成第三方库: 当需要与不支持 React 的第三方库如 D3.js、Chart.js 等集成时Refs 提供了一种访问和控制 DOM 的方式。焦点控制: 控制输入框、模态框等组件的焦点状态。
注意事项
避免滥用 Refs: 在大多数情况下应该优先考虑使用 React 的数据驱动和状态管理方式而不是直接操作 DOM。Refs 和函数式组件: 在函数式组件中确保使用 useRef 钩子来创建 Ref 对象而不是直接操作 DOM。
通过使用 Refs在 React 中可以安全地获取和操作 DOM 元素同时保持 React 的组件化和声明式编程模型的优势。
3.组件间通信
在 React 中组件间通信是非常常见和重要的一部分特别是在大型应用程序中不同组件之间需要相互传递数据、状态或触发特定行为。以下是几种主要的 React 组件间通信方式
1. Props 属性传递
Props属性是 React 中组件间通信最基础和常见的方式。通过将数据或函数作为属性传递给子组件可以实现父组件向子组件的数据传递。
父组件传递数据给子组件
// ParentComponent.jsx
import React from react;
import ChildComponent from ./ChildComponent;const ParentComponent () {const data Hello from parent;return (divChildComponent message{data} //div);
};export default ParentComponent;子组件接收并使用 Props 数据
// ChildComponent.jsx
import React from react;const ChildComponent (props) {return (divp{props.message}/p/div);
};export default ChildComponent;2. Callback 函数传递
通过将回调函数作为 Props 传递给子组件子组件可以调用该函数并将数据或事件传递回父组件。
父组件定义回调函数并传递给子组件
// ParentComponent.jsx
import React, { useState } from react;
import ChildComponent from ./ChildComponent;const ParentComponent () {const [message, setMessage] useState();const handleCallback (data) {setMessage(data);};return (divpMessage from child: {message}/pChildComponent callback{handleCallback} //div);
};export default ParentComponent;子组件调用回调函数并传递数据
// ChildComponent.jsx
import React from react;const ChildComponent (props) {const sendDataToParent () {const data Hello from child;props.callback(data);};return (divbutton onClick{sendDataToParent}Send Data/button/div);
};export default ChildComponent;3. Context API
Context API 提供了一种在组件树中传递数据的方法避免了通过 Props 层层传递数据的繁琐过程。适合在多层级嵌套的组件中使用允许跨越组件层级直接传递数据。
创建 Context 对象并提供数据
// MyContext.js
import React from react;const MyContext React.createContext();export const MyProvider MyContext.Provider;
export const MyConsumer MyContext.Consumer;使用 Context 提供数据并在子组件中消费
// ParentComponent.jsx
import React from react;
import { MyProvider } from ./MyContext;
import ChildComponent from ./ChildComponent;const ParentComponent () {const data Hello from context;return (MyProvider value{data}ChildComponent //MyProvider);
};export default ParentComponent;在子组件中消费 Context 中的数据
// ChildComponent.jsx
import React, { useContext } from react;
import { MyContext } from ./MyContext;const ChildComponent () {const data useContext(MyContext);return (divp{data}/p/div);
};export default ChildComponent;4. Redux 或其他状态管理工具
对于大型应用程序中复杂的状态管理需求可以使用 Redux 或其他状态管理工具如 MobX来集中管理应用程序的状态并通过全局状态来实现组件间通信。这种方式适合需要多个组件共享状态或频繁更新状态的场景。
选择合适的通信方式
Props 传递简单、直观适用于父子组件间的数据传递。Callback 函数父组件可以向子组件传递函数来处理子组件中的事件适合于子组件向父组件传递数据或事件。Context API适用于跨组件层级传递数据避免 Props 层层传递的麻烦。Redux 或其他状态管理工具适用于需要全局状态管理或复杂的状态更新和同步需求的应用程序。
根据具体的场景和需求选择适合的组件间通信方式是提高 React 应用开发效率和可维护性的关键。
4.useEffect
useEffect 是 React Hooks 中非常重要的一个钩子函数用于在函数组件中执行副作用操作。副作用操作通常包括订阅数据、手动操作 DOM 和执行数据获取等。
基本用法
import React, { useEffect, useState } from react;const MyComponent () {// 定义一个状态来存储数据const [data, setData] useState(null);// useEffect 第一个参数是一个函数第二个参数是一个数组useEffect(() {// 在组件加载后和每次更新后执行// 这里可以进行数据获取、订阅操作、手动 DOM 更新等异步操作fetchData();// 清理函数可选用于清理副作用return () {cleanupFunction();};}, []); // 空数组意味着只在组件加载后执行一次const fetchData async () {// 异步操作示例获取数据const result await fetch(https://api.example.com/data);const data await result.json();setData(data);};const cleanupFunction () {// 清理函数比如清除订阅或取消定时器// 在组件卸载时执行};return (div{data ? (pData loaded: {JSON.stringify(data)}/p) : (pLoading.../p)}/div);
};export default MyComponent;useEffect 的工作原理
第一个参数effect一个函数包含需要执行的副作用操作可以是数据获取、订阅操作、DOM 操作等异步任务。第二个参数dependencies 数组可选参数指定 effect 的依赖项。当依赖项发生变化时effect 就会重新执行。如果不传递该参数每次组件更新时都会执行 effect。
依赖项的作用
空数组 []effect 仅在组件加载和卸载时执行相当于 componentDidMount 和 componentWillUnmount 生命周期的结合体。包含状态或属性的数组effect 会在依赖项中的状态或属性发生变化时执行。比如 [count] 会在 count 状态更新时执行 effect。不传递第二个参数effect 在每次组件更新时都会执行相当于 componentDidUpdate 生命周期。
清理副作用
在 effect 函数中可以返回一个清理函数用于清理副作用比如取消订阅、清除定时器等。这样可以避免内存泄漏和无效的异步操作。
useEffect(() {const subscription subscribeToData();return () {subscription.unsubscribe(); // 清理订阅};
}, [dependency]);总结
useEffect 是 React Hooks 提供的强大工具用于处理函数组件中的副作用操作。通过指定依赖项数组可以精确控制 effect 的执行时机避免不必要的重复执行提高组件性能和可维护性。
5.自定义Hook
自定义 Hook 是 React 中的一个强大功能它允许你将组件逻辑提取到可复用的函数中。自定义 Hook 的命名通常以 use 开头。
创建一个自定义 Hook
我们将创建一个简单的自定义 Hook useCounter它管理一个计数器的状态并提供增加和减少计数器的方法。
Step 1: 定义自定义 Hook
import { useState } from react;const useCounter (initialValue 0) {const [count, setCount] useState(initialValue);const increment () setCount(count 1);const decrement () setCount(count - 1);return { count, increment, decrement };
};export default useCounter;Step 2: 使用自定义 Hook
你可以在任意函数组件中使用这个自定义 Hook
import React from react;
import useCounter from ./useCounter;const CounterComponent () {const { count, increment, decrement } useCounter(10);return (divpCount: {count}/pbutton onClick{increment}Increment/buttonbutton onClick{decrement}Decrement/button/div);
};export default CounterComponent;自定义 Hook 的优势
逻辑复用将重复使用的逻辑提取到自定义 Hook 中使代码更加模块化和可复用。更清晰的组件结构通过将复杂逻辑抽离到自定义 Hook 中组件代码变得更简洁和易读。状态隔离每次调用自定义 Hook 都会生成独立的状态互不影响。
复杂的自定义 Hook 示例
创建一个自定义 Hook useFetch 来处理数据获取
Step 1: 定义 useFetch Hook
import { useState, useEffect } from react;const useFetch (url) {const [data, setData] useState(null);const [loading, setLoading] useState(true);const [error, setError] useState(null);useEffect(() {const fetchData async () {try {const response await fetch(url);if (!response.ok) {throw new Error(Network response was not ok);}const data await response.json();setData(data);} catch (error) {setError(error);} finally {setLoading(false);}};fetchData();}, [url]);return { data, loading, error };
};export default useFetch;Step 2: 使用 useFetch Hook
import React from react;
import useFetch from ./useFetch;const DataComponent () {const { data, loading, error } useFetch(https://api.example.com/data);if (loading) return pLoading.../p;if (error) return pError: {error.message}/p;return (divpre{JSON.stringify(data, null, 2)}/pre/div);
};export default DataComponent;总结
自定义 Hook 允许你将组件逻辑提取到可复用的函数中提高代码的可读性和维护性。通过自定义 Hook可以更方便地复用逻辑、管理复杂的状态和副作用从而简化组件代码。