新版本 React 推荐使用函数式组件设计,状态相关处理推荐使用 Hooks,接下来通过 class component 和 function component 进行对比讲解;
React 的基础语法和概念是构建 React 应用程序的核心;以下是对 React 基础语法的详细说明,包括 props、state、条件渲染、事件处理和组件传值等;
Function Component (推荐)
Props
-
函数式组件通过参数来接收 props;
-
示例:
import { createRoot } from 'react-dom/client'; function Welcome(props) { return <h1>Hello, {props.name}</h1>; } function App() { return ( <div> <Welcome name="Sara" /> <Welcome name="Cahal" /> <Welcome name="Edite" /> </div> ); } const root = createRoot(document.getElementById('root')); root.render(<App />);
State
-
函数式组件使用 useState Hook 来管理状态;
-
示例:
import { createRoot } from "react-dom/client"; import { useState, useEffect } from "react"; function Clock() { const [date, setDate] = useState(new Date()); useEffect(() => { const timerID = setInterval(() => tick(), 1000); return () => clearInterval(timerID); }, []); const tick = () => { setDate(new Date()); }; return ( <div> <h1>Hello, world!</h1> <h2>It is {date.toLocaleTimeString()}.</h2> </div> ); } const root = createRoot(document.getElementById("root")); root.render(<Clock />);
条件渲染
-
使用条件运算符或逻辑运算符来实现条件渲染;
-
示例:
import { createRoot } from "react-dom/client"; function Greeting(props) { const isLoggedIn = props.isLoggedIn; return ( <div>{isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign up.</h1>}</div> ); } const root = createRoot(document.getElementById("root")); root.render(<Greeting isLoggedIn={true} />);
事件处理
-
函数式组件通过内联函数或自定义函数来处理事件;
-
示例:
import { createRoot } from "react-dom/client"; import { useState } from 'react'; function Toggle() { const [isToggleOn, setIsToggleOn] = useState(true); const handleClick = () => { setIsToggleOn(!isToggleOn); }; return ( <button onClick={handleClick}> {isToggleOn ? 'ON' : 'OFF'} </button> ); } const root = createRoot(document.getElementById("root")); root.render(<Toggle />);
组件传值
-
父组件可以通过 props 向子组件传递数据和函数;
-
示例:
import { createRoot } from "react-dom/client"; import { useState } from 'react'; function Parent() { const [message, setMessage] = useState(''); // 将函数传递给子组件,组件通过向该函数传递参数来实现参数传递 const handleChildData = (data) => { setMessage(data); }; return ( <div> <Child onChildData={handleChildData} /> <p>Message from child: {message}</p> </div> ); } function Child(props) { const sendData = () => { props.onChildData('Hello from Child'); }; return ( <div> <button onClick={sendData}>Send Data to Parent</button> </div> ); } const root = createRoot(document.getElementById("root")); root.render(<Parent />);
列表和 Key
-
渲染列表时,需要为每个列表项提供一个唯一的 key 属性;
-
示例:
import { createRoot } from "react-dom/client"; function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => <li key={number.toString()}> {number} </li> ); return ( <ul>{listItems}</ul> ); } const numbers = [1, 2, 3, 4, 5]; const root = createRoot(document.getElementById("root")); root.render(<NumberList numbers={numbers} />);
表单处理
-
函数式组件使用 useState Hook 来处理表单数据;
-
示例:
import { createRoot } from "react-dom/client"; import { useState } from 'react'; function NameForm() { const [value, setValue] = useState(''); const handleChange = (event) => { setValue(event.target.value); }; const handleSubmit = (event) => { alert('A name was submitted: ' + value); event.preventDefault(); }; return ( <form onSubmit={handleSubmit}> <label> Name: <input type="text" value={value} onChange={handleChange} /> </label> <input type="submit" value="Submit" /> </form> ); }; const root = createRoot(document.getElementById("root")); root.render(<NameForm />);
Class Component
Props
-
props 是组件的属性,是从父组件传递到子组件的数据;props 是只读的,子组件只能读取而不能修改它们;
-
示例:
import { createRoot } from "react-dom/client"; import { Component } from 'react'; class Welcome extends Component { render() { return <h1>Hello, {this.props.name}</h1>; } } function App() { return ( <div> <Welcome name="Sara" /> <Welcome name="Cahal" /> <Welcome name="Edite" /> </div> ); } const root = createRoot(document.getElementById("root")); root.render(<App />);
State
-
state 是组件内部的数据状态;state 是可变的,可以通过调用 this.setState 方法来更新状态,从而触发重新渲染;
-
示例:
import { createRoot } from "react-dom/client"; import { Component } from 'react'; class Clock extends Component { constructor(props) { super(props); this.state = { date: new Date() }; } componentDidMount() { this.timerID = setInterval(() => this.tick(), 1000); } componentWillUnmount() { clearInterval(this.timerID); } tick() { this.setState({ date: new Date() }); } render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2> </div> ); } } const root = createRoot(document.getElementById("root")); root.render(<Clock />);
条件渲染
-
根据某个条件来决定渲染哪个组件或内容。可以使用 JavaScript 中的条件运算符,如 if、else 或三元运算符;
-
示例:
import { createRoot } from "react-dom/client"; import { Component } from 'react'; class Greeting extends Component { render() { return (<div>{this.props.isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign up.</h1>}</div>); } } const root = createRoot(document.getElementById("root")); root.render(<Greeting isLoggedIn={true} />);
事件处理
-
React 的事件处理类似于 DOM 事件处理,但有一些语法上的不同;事件命名采用小驼峰命名法,处理函数通过 {} 传递;
-
示例:
import { createRoot } from "react-dom/client"; import { Component } from 'react'; class Toggle extends Component { constructor(props) { super(props); this.state = { isToggleOn: true }; // 绑定事件处理函数 this.handleClick = this.handleClick.bind(this); } handleClick() { this.setState(state => ({ isToggleOn: !state.isToggleOn })); } render() { return ( <button onClick={this.handleClick}> {this.state.isToggleOn ? 'ON' : 'OFF'} </button> ); } } const root = createRoot(document.getElementById("root")); root.render(<Toggle />);
组件传值
-
父组件可以通过 props 向子组件传递数据和函数,子组件可以调用父组件传递的函数来传递数据回父组件;
-
示例:
import { createRoot } from "react-dom/client"; import { Component } from 'react'; class Parent extends Component { constructor(props) { super(props); this.state = { message: '' }; this.handleChildData = this.handleChildData.bind(this); } handleChildData(data) { this.setState({ message: data }); } render() { return ( <div> <Child onChildData={this.handleChildData} /> <p>Message from child: {this.state.message}</p> </div> ); } } class Child extends Component { sendData = () => { this.props.onChildData('Hello from Child'); } render() { return ( <div> <button onClick={this.sendData}>Send Data to Parent</button> </div> ); } } const root = createRoot(document.getElementById("root")); root.render(<Parent />);
列表和 Key
-
在 React 中渲染列表时,需要为每个列表项提供一个唯一的 key 属性,以便 React 能够有效地更新和重新渲染列表;
-
示例:
import { createRoot } from "react-dom/client"; import { Component } from 'react'; class NumberList extends Component { render() { return ( <ul> {this.props.numbers.map((number) => <li key={number.toString()}> {number} </li> )} </ul> ); } } const numbers = [1, 2, 3, 4, 5]; const root = createRoot(document.getElementById("root")); root.render(<NumberList numbers={numbers} />);
表单处理
-
React 表单元素的值通常由组件的 state 控制,这些表单元素称为 “受控组件”;
-
示例:
import { createRoot } from "react-dom/client"; import { Component } from 'react'; class NameForm extends Component { constructor(props) { super(props); this.state = { value: '' }; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({ value: event.target.value }); } handleSubmit(event) { alert('A name was submitted: ' + this.state.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> <label> Name: <input type="text" value={this.state.value} onChange={this.handleChange} /> </label> <input type="submit" value="Submit" /> </form> ); } } const root = createRoot(document.getElementById("root")); root.render(<NameForm />);
React✍️ 生命周期
上一篇