React 基础语法

新版本 React 推荐使用函数式组件设计,状态相关处理推荐使用 Hooks,接下来我们通过 class component 和 function component 进行对比讲解。

React 的基础语法和概念是构建 React 应用程序的核心。以下是对 React 基础语法的详细说明,包括 props、state、条件渲染、事件处理和组件传值等。

1. Class Component

1.1. Props

props 是组件的属性,是从父组件传递到子组件的数据。props 是只读的,子组件只能读取而不能修改它们。

javascript 复制代码
import React from 'react';
import ReactDOM from 'react-dom';

function Welcome(props) {
    return <h1>Hello, {props.name}</h1>;
}

function App() {
    return (
        <div>
            <Welcome name="Sara" />
            <Welcome name="Cahal" />
            <Welcome name="Edite" />
        </div>
    );
}

ReactDOM.render(<App />, document.getElementById('root'));

1.2. State

state 是组件内部的数据状态。state 是可变的,可以通过调用 this.setState 方法来更新状态,从而触发重新渲染。

javascript 复制代码
import React from 'react';
import ReactDOM from 'react-dom';

class Clock extends React.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>
        );
    }
}

ReactDOM.render(<Clock />, document.getElementById('root'));

1.3. 条件渲染

根据某个条件来决定渲染哪个组件或内容。可以使用 JavaScript 中的条件运算符,如 if、else 或三元运算符。

javascript 复制代码
function UserGreeting(props) {
    return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
    return <h1>Please sign up.</h1>;
}

function Greeting(props) {
    const isLoggedIn = props.isLoggedIn;
    if (isLoggedIn) {
        return <UserGreeting />;
    }
    return <GuestGreeting />;
}

ReactDOM.render(
    <Greeting isLoggedIn={false} />,
    document.getElementById('root')
);

1.4. 事件处理

React 的事件处理类似于 DOM 事件处理,但有一些语法上的不同。事件命名采用小驼峰命名法,处理函数通过 {} 传递。

javascript 复制代码
class Toggle extends React.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>
        ); 
    }
}

ReactDOM.render(
    <Toggle />,
    document.getElementById('root')
);

1.5. 组件传值

父组件可以通过 props 向子组件传递数据和函数,子组件可以调用父组件传递的函数来传递数据回父组件。

javascript 复制代码
class Parent extends React.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 React.Component {
    sendData = () => {
        this.props.onChildData('Hello from child');
    }

    render() {
        return (
            <div>
                <button onClick={this.sendData}>Send Data to Parent</button>
            </div>
        );
    }
}

ReactDOM.render(
    <Parent />,
    document.getElementById('root')
);

1.6. 列表和 Key

在 React 中渲染列表时,需要为每个列表项提供一个唯一的 key 属性,以便 React 能够有效地更新和重新渲染列表。

javascript 复制代码
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];
ReactDOM.render(
    <NumberList numbers={numbers} />,
    document.getElementById('root')
);

1.7. 表单处理

React 表单元素的值通常由组件的 state 控制,这些表单元素称为"受控组件"。

javascript 复制代码
class NameForm extends React.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>
        );
    }
}

ReactDOM.render(
    <NameForm />,
    document.getElementById('root')
);

2. Class Component

目前 React 应用主流编码方式是函数式组件,后续我们的课程也均是以函数式组件为主,同学们重点学习。

2.1. Props

函数式组件通过参数来接收 props。

javascript 复制代码
import React from 'react';
import ReactDOM from 'react-dom';

function Welcome(props) {
    return <h1>Hello, {props.name}</h1>;
}

function App() {
    return (
        <div>
            <Welcome name="Sara" />
            <Welcome name="Cahal" />
            <Welcome name="Edite" />
        </div>
    );
}

ReactDOM.render(<App />, document.getElementById('root'));

2.2. State

函数式组件使用 useState Hook 来管理状态。

javascript 复制代码
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';

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>
    );
}

ReactDOM.render(<Clock />, document.getElementById('root'));

2.3. 条件渲染

使用条件运算符或逻辑运算符来实现条件渲染。

javascript 复制代码
import React from 'react';
import ReactDOM from 'react-dom';

function Greeting(props) {
    const isLoggedIn = props.isLoggedIn;
    return (
        <div>
            {isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign up.</h1>}
        </div>
    );
}

ReactDOM.render(
    <Greeting isLoggedIn={false} />,
    document.getElementById('root')
);

2.4. 事件处理

函数式组件通过内联函数或自定义函数来处理事件。

javascript 复制代码
import React, { useState } from 'react';
import ReactDOM from 'react-dom';

function Toggle() {
    const [isToggleOn, setIsToggleOn] = useState(true);

    const handleClick = () => {
        setIsToggleOn(!isToggleOn);
    };

    return (
        <button onClick={handleClick}> 
            {isToggleOn ? 'ON' : 'OFF'}
        </button>
    );
}

ReactDOM.render(<Toggle />, document.getElementById('root'));

2.5. 组件传值

父组件可以通过 props 向子组件传递数据和函数。

javascript 复制代码
import React, { useState } from 'react';
import ReactDOM from 'react-dom';

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>
    );
}

ReactDOM.render(<Parent />, document.getElementById('root'));

2.6. 列表和 Key

渲染列表时,需要为每个列表项提供一个唯一的 key 属性。

javascript 复制代码
import React from 'react';
import ReactDOM from 'react-dom';

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];
ReactDOM.render(
    <NumberList numbers={numbers} />,
    document.getElementById('root')
);

2.7. 表单处理

函数式组件使用 useState Hook 来处理表单数据。

javascript 复制代码
import React, { useState } from 'react';
import ReactDOM from 'react-dom';

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>
    );
}

ReactDOM.render(<NameForm />, document.getElementById('root'));
相关推荐
全栈探索者3 天前
@Component + struct = 你的新函数组件——React 开发者的鸿蒙入门指南(第 2 期)
react·harmonyos·arkts·前端开发·deveco studio·鸿蒙next·函数组件
realhuizhu3 天前
为什么程序员配出的颜色像"斑斓的灰"?因为你还在靠直觉
前端开发·ai工具·ui设计·deepseek·程序员提升
奔跑的呱呱牛4 天前
viewer-utils 图片预览工具库
javascript·vue·react
HetFrame4 天前
一种纯前端实现 Markdown 内容即时分享的思路
html·react·链接·markdown·工具
小浣熊喜欢揍臭臭4 天前
qiankun微服务搭建之【react+nextJs】
微服务·react
gentle coder6 天前
【langchain】agent部署的基础入门代码(持续更新中~)
python·langchain·react
RichardLau_Cx7 天前
【保姆级实操】MediaPipe SDK/API 前端项目接入指南(Web版,可直接复制代码)
前端·vue·react·webassembly·mediapipe·手部追踪·前端计算机视觉
小小工匠7 天前
大模型开发 - 零手写 AI Agent:深入理解 ReAct 模式与 Java 实现
人工智能·react
雪域迷影8 天前
MacOS中运行Next.js项目注册新用户时MongoDB报错MongoServerError
mongodb·macos·react·next.js
Highcharts.js8 天前
使用Highcharts与React集成 官网文档使用说明
前端·react.js·前端框架·react·highcharts·官方文档