本文将介绍 React 基础知识。
React 是一个非常棒的库,可以用来构建伟大的产品。
React 是一个非常棒的库,可以用来构建伟大的产品。
->这篇文章纯属个人经验分享,如果有什么错误,欢迎在我的帖子下留言指正,这对我的帮助非常大。
什么是JSX?
const element = <h1>Hello, world!</h1>;
它包含了 JavaScript 和 JSX,这将改变你对语言模板的看法。JSX 渲染的是 HTML,其内部包含 JavaScript 逻辑。
为什么是 JSX?
React 在 UI 中融入了事件逻辑,例如事件的处理方式、状态的改变方式以及数据在显示前的处理方式等等……
React 并没有人为地将 UI 和逻辑分离到不同的文件中,而是将它们合并到一个文件中。这将有助于编写清晰易懂、易于维护的代码。(详情请见SoC )
渲染元素
在 React 模板中,当你创建一个新的组件时,需要<div id="root"></div>
在 public 文件夹下的 index.html 文件中创建一个 `<div>` 标签。这是一个 DOM 节点,React 会将每个元素渲染到这个 `<div>` 标签内。
仅使用 React 构建的应用程序通常只有一个根 DOM 节点。
ReactDOM.render(<SampleComponent />, document.getElementById("sampleElement"))
public/index.html
<!-- .... -->
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
<!-- .... -->
src/index.js
ReactDOM.render(<App />, document.getElementById("root"));
组件和属性
组件“允许你将 UI 拆分成独立的、可重用的组件,并单独考虑每个组件。” - reactjs.org。
组件返回一个 React 元素。
Props 是一个对象数据参数,只读,组件内部只接受一个“props”参数。
Props 是一个对象,只读,一个组件只能有一个 props。
例子 :
function App() {
return (
<div className="App">
<Avatar name="Ha Tuan" source="https://picsum.photos/400" />
</div>
);
}
function Avatar(props) {
return (
<div>
<img src={props.source} />
<p>{props.name}</p>
</div>
);
}
状态和生命周期
基本上,State 是 React.Component 类中的一个对象属性,类似于 JavaScript 类中的一个对象。您可以更改 state 中的值或删除键对象。
class Counter extends Component {
state = {
counter: 0
};
handleIncrement = () => this.setState({ counter: this.state.counter + 1 });
handleDecrement = () => this.setState({ counter: this.state.counter - 1 });
render() {
return (
<div>
<button onClick={this.handleIncrement}>+</button>
<span>{this.state.counter}</span>
<button onClick={this.handleDecrement}>-</button>
</div>
);
}
}
有关生命周期的更多信息,请访问programmingwithmosh.com 。
状态和生命周期在 React 组件中非常重要。
处理事件
“使用 React 元素处理事件与使用 DOM 元素处理事件非常相似。两者之间存在一些语法差异:
- React 事件的命名采用驼峰式命名法,而不是小写字母。
- 使用 JSX 时,你需要传递一个函数作为事件处理程序,而不是一个字符串。
reactjs.org
以下是一些在 React 元素中处理事件的方法:
- 使用箭头函数
class Alert extends Component {
handleOnClick = () => {
alert("Method is called");
};
render() {
return (
<div>
<button onClick={this.handleOnClick}>Click me for show alert !</button>
</div>
);
}
}
- 构造函数中的绑定事件
class Alert extends Component {
constructor(props) {
super(props);
this.handleOnClick = this.handleOnClick.bind(this);
}
handleOnClick() {
alert("Method is called");
}
render() {
return (
<div>
<button onClick={this.handleOnClick}>Click me for show alert !</button>
</div>
);
}
}
- 在函数组件中使用处理事件
function Alert() {
function handleOnClick(e) {
alert("Alert is called");
}
return (
<div>
<button onClick={handleOnClick}>Click me for show alert !</button>
</div>
);
}
条件渲染
- 使用 if else 内联或原始方式。
function LogoutButton(props) {
return <button onClick={props.OnClick}>Log out</button>;
}
function LoginButton(props) {
return <button onClick={props.OnClick}>Log in</button>;
}
class Authenticate extends Component {
state = {
isAuthenticate: false
};
handleOnLogout = () => this.setState({ isAuthenticate: false });
handleOnLogin = () => this.setState({ isAuthenticate: true });
render() {
const element = this.state.isAuthenticate ? (
<LogoutButton OnClick={this.handleOnLogout} />
) : (
<LoginButton OnClick={this.handleOnLogin} />
);
return (
<div>
<h1>Page Authenticate</h1>
{element}
</div>
);
}
}
- 使用内联 If 语句,并结合 [ 逻辑 && 运算符 ] 或 [ 逻辑 || 运算符 ]
class ShoppingCart extends Component {
state = {
items: 0
};
render() {
return (
<div>
<h1>Shopping Cart</h1>
{/* try both method */}
{this.state.items <= 0 && <p>Nothing item in cart.</p>}
{this.state.items <= 0 || <p>Nothing item in cart.</p>}
</div>
);
}
}
列表和键
在 React 中,通常使用 `map()` 方法或任何你想要的方法。这用于渲染组件中的元素。做一个简单的待办事项列表来理解:
import React, { Component } from "react";
class TodoList extends Component {
state = {
todos: [
{
id: 0,
title: "Learing react"
}
],
title: ""
};
handleOnChange = e => {
this.setState({
title: e.target.value
});
};
handleOnRemove = id => {
this.setState({
todos: this.state.todos.filter(todo => todo.id !== id)
});
};
handleOnAddTodo = e => {
e.preventDefault();
const newTodo = {
id: this.state.todos.length + 1,
title: this.state.title
};
this.setState({
todos: [newTodo, ...this.state.todos],
title: ""
});
};
render() {
const todoList = this.state.todos.map((todo, index) => (
// change key={todo.id} to key={index} you are going to see something wrong in this case
<TodoItem onRemove={this.handleOnRemove} {...todo} key={todo.id} />
));
return (
<div>
<form>
<input
value={this.state.title}
onChange={this.handleOnChange}
placeholder="add something"
/>
<button onClick={this.handleOnAddTodo}>add</button>
</form>
<hr />
{todoList}
</div>
);
}
}
function TodoItem(props) {
return <li onClick={e => props.onRemove(props.id)}>{props.title}</li>;
}
export default TodoList;
“键(Key)帮助 React 识别哪些元素发生了变化、被添加或被删除。应该给数组中的元素赋予键,以便为元素提供稳定的标识。” - reactjs.org
如果数组发生更改(例如删除数组中的对象),请不要使用索引作为键。因为这可能会导致组件状态出现问题。
表格
“HTML 表单元素在 React 中的工作方式与其他 DOM 元素略有不同,因为表单元素本身就保留了一些内部状态。” - reactjs.org
React 中的一些控件表单
<input type="text" name="Tittle" className="form-control" />
<textarea value="" name="Description" className="form-control" />
<select value="" onChange={this.someHandleOnChange} multiple={true}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
但是,当您拥有很多控制权,而数据类型相同时,您可以将所有 onChange 事件放在一个函数中,如下所示,这样可以节省时间并使代码更简洁:
handleOnChange = (e) => {
this.setState({[e.target.name] : e.target.value});
}
数据类型为文件,您可以在我的文章“使用 multer 在 Nodejs 中上传文件”中找到相关信息。
概括
React 是一个很棒的库,如果你看到感兴趣的项目,可以尝试一下。这个库的关键在于状态管理,因为如果项目规模过大,应用程序的状态可能会变得非常混乱。在这种情况下,我认为我们应该了解 Redux 并将其应用到应用程序中,这样可以节省时间。但是,对于初学者或不熟悉 JavaScript 的人来说,React 并不友好。我建议我们应该掌握一些 JavaScript 的面向对象编程 (OOP) 知识,这对我们节省时间非常有帮助。
感谢阅读。祝您
愉快!