学习如何轻松构建可伸缩的 React 应用程序:编写组件
编程中常见的命名方式有:
驼峰式命名法(Camel Case),也叫小驼峰式命名法(Lower Camel Case)
const camelCase = "camelCase";
帕斯卡命名法(Pascal Case),也叫大驼峰式命名法(Upper Camel Case)
const PascalCase = "PascalCase";
在 React 中,组件的命名方式是大驼峰式命名法,即组件的名称必须以大写字母开头。
import React from "react";
const MyComponent = () => {
return <div>My Component</div>;
};
export default MyComponent;
函数组件是普通的 JavaScript 函数,它接收 props
作为输入并返回一个 React 组件。
可以是一个箭头函数:
import React from "react";
const MyComponent = (props) => {
return <div>My Component</div>;
};
export default MyComponent;
或普通函数:
import React from "react";
function MyComponent(props) {
return <div>My Component</div>;
}
export default MyComponent;
函数组件具有一些常见的 hook 。React hooks 使得大多数开发人员能够构建可伸缩的 React 应用程序。
useState
是 React 中最常用的 hook 之一,它用于在函数式组件中存储状态值(对象、字符串、布尔值等),这些值在组件的生命周期中进行变更。useState
接受一个初始值,如果是字符串则可以为空字符串,这个值可以在组件的生命周期中进行更新。
import React, { useState } from "react";
const MyComponent = () => {
const [name, setName] = useState("");
return (
<div>
<h1>My Component</h1>
<input type="text" value={name} onChange={(e) => setName(e.target.value)} />
</div>
);
};
export default MyComponent;
useRef
方法也是大多数函数组件中常用的 React hooks 之一。useRef
方法常用于指向 DOM 中的一个元素,可用于创建不受控制的元素。
import React, { useRef } from "react";
const MyComponent = () => {
const inputRef = useRef(null);
const browseFile = () => {
if (inputRef.current) {
inputRef.current.click();
}
};
return (
<div>
<input type="file" ref={inputRef} />
<button onClick={browseFile}>Browse File</button>
</div>
);
};
export default MyComponent;
useEffect
方法也是大多数功能组件中常用的 React hook 。useEffect
方法是一种异步钩子,让我们可以在组件上执行异步任务,这些异步任务包括调用 API 并通过 useState
保存数据。
useEffect
接受两个参数,分别是:
useEffect
会在每次渲染时执行useEffect
只会在组件挂载时执行useEffect
会在组件挂载时执行,以及当数组中的任何值发生变化时执行import React, { useState, useEffect } from "react";
const MyComponent = () => {
const [name, setName] = useState("");
const [count, setCount] = useState(0);
useEffect(() => {
console.log("render component");
});
useEffect(() => {
console.log("componentDidMount");
return () => {
console.log("componentWillUnmount");
};
}, []);
useEffect(() => {
console.log("componentDidUpdate");
document.title = `You clicked ${count} times`;
}, [count]);
return (
<div>
<h1>My Component</h1>
<input type="text" value={name} onChange={(e) => setName(e.target.value)} />
<button onClick={() => setCount(count + 1)}>Click Me</button>
</div>
);
};
export default MyComponent;
类组件是继承自 React.component
的子类组件,这个类组件接受 props
并渲染它们,它以一个 constructor
开始,这个 constructor
会被超类调用。
import React from "react";
class MyComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return <div>My Component</div>;
}
}
export default MyComponent;
类组件有一些常见的生命周期方法:
componentDidMount
componentDidUpdate
该生命周期方法在 React 组件生命周期的挂载阶段被调用,这个方法可以帮助我们在向用户展示数据之前修改 React 组件的内容。
import React from "react";
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "",
};
}
componentDidMount() {
this.setState({ name: "Cell" });
}
render() {
return <div>My name is {this.state.name}</div>;
}
}
export default MyComponent;
该生命周期方法在组件更新后被调用:
import React from "react";
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "",
};
}
componentDidMount() {
this.setState({ name: "Cell" });
}
componentDidUpdate() {
console.log("componentDidUpdate");
}
render() {
return <div>My name is {this.state.name}</div>;
}
}
export default MyComponent;
React 组件是构建小型到强大应用程序的方式。这些 React 组件需要以良好的方式进行结构化,以便于进行测试、扩展和易于发现错误。
以下是保持良好的 React 组件结构的最佳方法:
在 React 中,一定会在在组件之间共享数据,具体实现方式取决于状态变化的复杂程度和应用程序的大小。
以下是一些实现方式:
Props
Context
APIRedux
useReducer
Props
是在 React 中从一个组件传递数据到另一个组件的一种方式,props
是从父组件传递到子组件的对象。Props
是 properties
(属性)的缩写。
import React from "react";
const MyComponent = (props) => {
const { name, age } = props;
return (
<div>
<p>My name is {name}</p>
<p>My age is {age}</p>
</div>
);
};
const App = () => {
return <MyComponent name="Cell" age={18} />;
};
export default App;
Context API
也是一种从一个组件传递数据到另一个组件的方式。与 Props
的主要区别在于,Context API
不会在每个组件上从父组件传递到子组件。
Context API
有两个主要方法:
Provider
Provider
接受一个要传递给子组件的值Consumer
Consumer
允许调用组件订阅 context
更新import React from "react";
const MyContext = React.createContext();
const MyComponent = () => {
return (
<MyContext.Consumer>
{(data) => (
<div>
<p>My name is {data.name}</p>
<p>My age is {data.age}</p>
</div>
)}
</MyContext.Consumer>
);
};
const MyComponent2 = () => {
const data = React.useContext(MyContext);
return (
<div>
<p>My name is {data.name}</p>
<p>My age is {data.age}</p>
</div>
);
};
const App = () => {
return (
<MyContext.Provider value={{ name: "Cell", age: 18 }}>
<MyComponent />
<MyComponent2 />
</MyContext.Provider>
);
};
export default App;
Redux 是一个开源的 JavaScript 库,它保持全局状态以使应用程序具有一致的行为。
Redux 库包括以下三个部分:
import { createStore } from "redux";
const initialState = {
name: "",
age: 0,
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case "SET_NAME":
return {
...state,
name: action.payload,
};
case "SET_AGE":
return {
...state,
age: action.payload,
};
default:
return state;
}
};
const store = createStore(reducer);
store.subscribe(() => {
console.log(store.getState());
});
store.dispatch({ type: "SET_NAME", payload: "Cell" });
// { name: "Cell", age: 0 }
store.dispatch({ type: "SET_AGE", payload: 18 });
// { name: "Cell", age: 18 }
useReducer
方法也是在组件之间共享数据的一种方式。当您需要进行复杂状态更改时,可以使用 useReducer
方法。
useReducer
方法接受参数为初始状态和操作,返回当前状态和 dispatch
方法。
import { useReducer } from "react";
const initialState = {
name: "",
age: 0,
};
const reducer = (state, action) => {
switch (action.type) {
case "SET_NAME":
return {
...state,
name: action.payload,
};
case "SET_AGE":
return {
...state,
age: action.payload,
};
default:
return state;
}
};
const App = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>My name is {state.name}</p>
<p>My age is {state.age}</p>
<button onClick={() => dispatch({ type: "SET_NAME", payload: "Cell" })}>Set Name</button>
<button onClick={() => dispatch({ type: "SET_AGE", payload: 18 })}>Set Age</button>
</div>
);
};
export default App;
受控组件数据是由 React 组件管理的,而非受控组件数据是由 浏览器或 DOM 处理。受控组件通常由用户输入或事件处理。
import React, { useState, useRef } from "react";
const controlledComponent = () => {
const [name, setName] = useState("");
const [age, setAge] = useState(0);
return (
<div>
<input type="text" value={name} onChange={(e) => setName(e.target.value)} />
<input type="number" value={age} onChange={(e) => setAge(e.target.value)} />
</div>
);
};
const uncontrolledComponent = () => {
const nameRef = useRef();
const ageRef = useRef();
const handleSubmit = () => {
console.log(nameRef.current.value);
console.log(ageRef.current.value);
};
return (
<div>
<input type="text" ref={nameRef} />
<input type="number" ref={ageRef} />
<button onClick={handleSubmit}>Submit</button>
</div>
);
};
const App = () => {
return (
<div>
<controlledComponent />
<uncontrolledComponent />
</div>
);
};
export default App;