React 备忘单(包含 React 18)
感谢阅读
您是否正在尝试进入React的世界,但却总是忘记如何做事并遇到障碍?
别担心,朋友,现在你不用再在黑暗中摸索了!这篇文章是一篇关于React 的记忆辅助文章(仅关注函数式组件)。
创建 React 应用
完整的React应用创建指南可在此处获取。如果您想快速启动某个应用,create-react-app
这是最佳选择。
// Initialize a new app
npx create-react-app my-app-name
OR
yarn create react-app my-app-name
// Run the app (default port is 3000)
cd my-app-name
npm start
OR
yarn start
渲染 React 组件
import ReactDOM from "react-dom/client";
import App from "./App";
// ...
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
功能组件
const Component = () => {
return <div>Hello World</div>;
};
先决条件:
- 首字母必须大写
- 必须返回JSX
从React 17开始,无需import React from 'react'
导入组件
Components
可以从其他文件导出和导入,从而促进代码拆分和可重用性。
默认导出
function Component = () =>
<div>Hello World</div>
export default Component
import Component from './Component'
function App = () => <Component />
命名导出
export function Component = () =>
<div>Hello World</div>
import { Component } from './Component'
function App = () => <Component />
延迟加载
function Component = () =>
<div>Hello World</div>
export default Component
import { lazy, Suspense } from 'react'
const Component = lazy(() => import('./Component'))
function App = () => (
<Suspense fallback={<div>Loading...</div>}>
<Component />
</Suspense>
)
JSX 规则
1. 必须返回单个元素
const Component = () => {
// INVALID: return <div>Hello</div><div>World</div>;
return <div>Hello World</div>;
};
或者
const Component = () => {
// `<React.Fragment>` can be replaced with just `<>`
// On wrapping the children with any element,
// you can create as many levels of nesting as you want
return (
<React.Fragment>
<div>Hello</div>
<div>World</div>
</React.Fragment>
);
};
2. 开始标签需要关闭(可以使用自关闭标签)
const Component = () => {
// INVALID: return <input>;
return <input />;
};
3. 使用 React 属性代替 HTML 属性
const Component = () => {
// INVALID: return <div class="foo">Hello World</div>;
return <div className="foo">Hello World</div>;
};
造型
如果你手动构建React应用,则需要添加css-loader
&style-loader
才能使用样式。幸运的是, React已预先配置好样式。webpack.config.js
create-react-app
CSS 导入
/* app.css */
.redText {
color: red;
}
import "./app.css";
function App() {
return <h1 className="redText">
Hello World
</h1>;
}
内联 CSS
const Component = () => {
return <div style={{ color: "red" }}>
Hello World
</div>;
};
CSS 模块
/* app.css */
.redText {
color: red;
}
import classes from "./app.css";
function App() {
return <h1 className={classes.redText}>
Hello World
</h1>;
}
嵌入 JavaScript
先决条件:
- 必须是具有返回值的表达式(也可以是JSX)
- 必须用花括号(
{}
)括起来
const Component = () => {
const isLoggedIn = true;
return <div>
{isLoggedIn ? "User is Authenticated" : <LogIn />}
</div>;
};
组件属性
这些是用于初始化组件的值。props
被接受为函数参数。
// no props
function App() {
return <Person name="Mike" age={29} />;
}
// with props
const Person = (props) => {
return (
<h1>
Name: {props.name}, Age: {props.age}
</h1>
);
};
// with destructured props
const Person = ({ name, age }) => {
return (
<h1>
Name: {name} Age: {age}
</h1>
);
};
孩子们
children
prop
是传递给组件并在组件内部渲染的特殊组件。
const Component = ({ children }) => {
return <div>{children}</div>;
};
const App = () => {
return (
<Component>
<h1>Hello World</h1>
</Component>
);
};
默认道具
// JavaScript-ish syntax
const Component = ({ name = "Mike" }) => {
return <div> {name} </div>;
};
或者
// React-ish syntax
const Component = ({ name }) => {
return <div> {name} </div>;
};
Component.defaultProps = {
name: "Mike",
};
列表
const people = [
{ id: 1, name: "Mike" },
{ id: 2, name: "Peter" },
{ id: 3, name: "John" },
];
function App() {
return people.map((person) => (
<div key={person.id}>{person.name}</div>;
));
}
是所有元素上可用的key
可选属性, Reactprop
内部使用它来跟踪哪些元素发生了变化。对于列表,强烈建议你添加。key
Prop 解构
Person
是一个接受 prop 的组件name
。
function App() {
return people.map(({id, ...person}) => (
<Person key={id} {...person} />;
));
}
活动
const clickHandler = () => alert("Hello World");
function App() {
return (
<>
<h1>Welcome to my app</h1>
<button onClick={clickHandler}>
Say Hi
</button>
</>
);
}
或内联...
function App() {
return (
<>
<h1>Welcome to my app</h1>
<button onClick={() => alert("Hello World")}>
Say Hi
</button>
</>
);
}
我们还可以将参数传递给处理程序
const clickHandler = (message) => alert(message);
function App() {
return (
<>
<h1>Welcome to my app</h1>
<button onClick={() => clickHandler("Hello World")}>
Say Hi
</button>
</>
);
}
事件默认将事件对象作为第一个参数传递。
const clickHandler = (event) => console.log(event.target);
function App() {
return (
<>
<h1>Welcome to my app</h1>
<button onClick={clickHandler}>
Say Hi
</button>
</>
);
}
你甚至可以从父级传递一个处理程序并在子级内部执行它
function Todo({item, onDelete}) {
return (
<div>
{item}
<button onClick={() => onDelete(item)} />
</div>
)
}
function Todos() {
const handleDelete = (todo) => {
const newTodos = todos.filter(item => item !== todo)
setTodos(() => newTodos)
}
return (
{todos.map((todo) => (
<Todo item={todo} onDelete={handleDelete}/>
))}
)
}
钩子
Hooks是一种函数,可以让你从函数组件中“钩入” React状态和生命周期功能。
先决条件:
- Hook总是以 'use' 前缀开头
- 只能在React 函数组件中调用
- 只能在功能组件的顶层调用
- 不能有条件地调用声明
useState
useState
是一个钩子,可让您管理功能组件中的状态。
function App() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffect
useEffect
是一个钩子,可让您访问功能组件中的生命周期方法。
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("Initialized");
// clean up function runs before the component is unmounted
return () => {
console.log("Cleaned up");
};
}, []); // empty array: run during mount only
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // array with count: run everytime `count` changes
return (
<div>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
使用上下文
useContext
是一个返回给定数据的钩子context
(React附带的状态管理工具)
const ThemeContext = createContext("light");
function App() {
return (
<ThemeContext.Provider value="light">
<Component />
</ThemeContext.Provider>
);
}
function Component() {
const theme = useContext(ThemeContext); // returns 'light'
return (
<div>
<p>The current theme is: {theme}</p>
</div>
);
}
useReducer
useReducer
是一个钩子,可以让你管理功能组件中的状态,但与useState
它使用Redux模式不同
function App() {
const [count, dispatch] = useReducer((state, action) => {
switch (action) {
case "increment":
return state + 1;
case "decrement":
return state - 1;
default:
throw new Error();
}
}, 0);
return (
<div>
<p>{count}</p>
<button onClick={() => dispatch("increment")}>
+
</button>
<button onClick={() => dispatch("decrement")}>
-
</button>
</div>
);
}
使用回调
该useCallback
钩子返回回调的记忆版本,其唯一目的是优化性能。
function App() {
const [count, setCount] = useState(0);
const increment = useCallback(() =>
setCount((c) => c + 1), []);
return (
<div>
<p>{count}</p>
<button onClick={increment}>+</button>
</div>
);
}
使用备忘录
该useMemo
钩子返回回调函数生成值的记忆版本。就像是一个性能优化钩子一样。useCallback
useMemo
function App() {
const [count, setCount] = useState(0);
const memoizedIncrement = useMemo(() => {
return () => setCount((c) => c + 1);
}, []);
return (
<div>
<p>{count}</p>
<button onClick={memoizedIncrement}>+</button>
</div>
);
}
useRef
该useRef
钩子返回一个 ,mutable ref object
其.current
属性被初始化为传入的参数 ( initialValue
)。除非手动更改,否则返回的对象将在组件的整个生命周期内持续存在。
function App() {
const inputRef = useRef(null);
const onButtonClick = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={onButtonClick}>
Focus on the input
</button>
</div>
);
}
useTransition
钩子让你将不太紧急的操作标记为useTransition
转换。
function App() {
const [input, setInput] = useState("");
const [data, setData] = useState([...items]);
const [isPending, startTransition] = useTransition();
useEffect(() => {
// input change is prioritized over filtering a long list
startTransition(() => {
setData(items.filter((i) => i.includes(input)));
});
}, [input]);
const updateInput = (e) => setInput(e.target.value);
return (
<div>
<input value={input} onChange={updateInput} />
<ul>
{data.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</div>
);
}
useDeferredValue
该useDeferredValue
钩子可以让你有意推迟更新值,这样它们就不会减慢页面的其他部分
function App() {
const deferredValue = useDeferredValue(value);
return <MyComponent value={deferredValue} />;
}
就这些啦!大家觉得我漏掉了什么,欢迎在评论区补充👇
快乐开发!
感谢阅读
需要一位顶级软件开发自由职业者来解决你的开发难题吗?在Upwork上联系我
想联系我吗?请在LinkedIn上联系我
关注我的博客,每两周在Medium上获取最新资讯
常问问题
这些是我经常收到的一些问题。希望这个常见问题解答部分能解决您的问题。
-
我是初学者,该如何学习前端 Web 开发?
可以参考以下文章: -
你能指导我吗?
抱歉,我工作已经很忙了,没时间指导任何人。