npx create-react-app react-basic
-
npx 是包管理器,用于执行 npm 包中的可执行文件。它允许在不全局安装包的情况下直接运行 npm 包中的命令。
-
create-react-app 是一个 React 应用程序的脚手架工具,它可以帮助你快速搭建起一个基于 React 的开发环境,包括构建、调试、测试等。
-
react-basic 是你要创建的 React 项目的名称。
// index.js
// 整个项目的入口 等于vue中的 main.ts
import React from "react";
import ReactDOM from "react-dom";
// 导入根组件
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
// App.js 根组件
function App() {
return (
<div className="App">
this is App
</div>
);
}
export default App;
什么是JSX? JSX 是 JavaScript 和 XML 的结合体,是 JavaScript 的语法扩展,需要通过解析工具解析,如 Babel。
JSX 使用 JavaScript 表达式:
- 引号传递字符串。
- 使用 JavaScript 变量。
- 函数或方法调用。
- 使用 JavaScript 对象。
let count = 100;
const AddCount = () => {
count++;
};
// 根组件
function App() {
return (
<div className="App">
this is App
{"hello"}
{count}
{AddCount()}
<div style={{ color: "red" }}>对象形式</div>
</div>
);
}
export default App;
列表遍历(对比 v-for):
const list = [
{
id: 1,
name: "Vue",
},
{
id: 2,
name: "React",
},
{
id: 3,
name: "Jquery",
},
];
// 根组件
function App() {
return (
<div className="App">
this is App
<ul>
{list.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
条件渲染(对比 v-if):
// 那 v-show 怎么处理嘞?
const isLogin = true;
// 根组件
function App() {
return (
<div className="App">
{isLogin && <div>已登录</div>}
{isLogin ? <div>三元已登录</div> : <div>三元未登录</div>}
</div>
);
}
事件绑定:(类比为 @click)
// 根组件
function App() {
const handleClick = () => {
console.log("被点击了");
};
return (
<div className="App">
<button onClick={handleClick}>点我测试</button>
</div>
);
}
// 使用箭头函数中转,可以传递自定义的参数,还可以同时获取点击的默认参数。Vue 中也是,但 Vue 中可以 $event 来获取默认参数。
function App() {
const handleClick = (e, name) => {
console.log("被点击了", e, name);
};
return (
<div className="App">
<button onClick={(e) => handleClick(e, "name")}>点我测试</button>
</div>
);
}
export default App;
组件: React 组件必须要首字母大写。组件当成标签用就可以了。
// 定义
function Button() {
return (
<>
<div>我是 button 组件</div>
</>
);
}
// 根组件
function App() {
return (
<div className="App">
<Button />
</div>
);
}
useState 使用: 是一个 React Hook 函数,添加响应式变量,相当于 Ref,Reactive。
useState 传入初始值,返回一个数组,第一个值是状态变量,第二个是修改方法。
import { useState } from "react";
function App() {
const [count, setCount] = useState(100);
return (
<div className="App">
<Button />
<button
onClick={() => {
setCount(count + 1);
}}
>
{count}
</button>
</div>
);
}
useState 的规则: 需要注意的点。
- 状态不可变,需要替换状态,不可以修改。修改不会引发视图更新。
- 对象类型的状态变量,始终传递全新的对象来修改。有点麻烦,后面用其他的库来处理这个。
import { useState } from "react";
// 根组件
function App() {
const [obj, setObj] = useState({ name: "离火塔" });
return (
<div className="App">
<button
onClick={() => {
setObj({ ...obj, name: "嘻嘻" });
}}
>
{obj.name}
</button>
</div>
);
}
React 样式写法:
// app.js
import "./index.css";
function App() {
return (
<div className="App">
<div style={{ color: "red", fontSize: "30px" }}>YYDS</div>
<div className="my-div">YYDS</div>
</div>
);
}
.my-div {
background-color: aqua;
}
Tips:
- 注意使用 React 时,如果遇到状态变量需要排序时,请使用 lodash 的排序方法。原生的 sort 会改变原数组。
- classnames 优化类名控制。是一个 JavaScript 库,方便使用的。跟 Vue 写法很像。
className={classNames('nav-item', { active: type === item.type })}
受控表单状态
受控表单状态类似于 Vue 中的 v-model 双向绑定。
import { useState } from "react"
function App() {
const [value, setValue] = useState("")
return (
<div className="App">
<input value={value} onChange={(e) => setValue(e.target.value)} type="text" />
</div>
)
}
React 获取 DOM 元素
React 获取 DOM 元素需要使用 useRef Hook 函数。
import { useRef } from "react"
function App() {
const inputRef = useRef(null)
const showDom = () => {
console.dir(inputRef.current)
}
return (
<div className="App">
<input type="text" ref={inputRef} />
<button onClick={showDom}>点我显示 DOM</button>
</div>
)
}
组件通信
1. 父子组件通信
父子组件通信与 Vue 的 props 类似。
function Son(props) {
console.log(props)
return <div>{props.name}</div>
}
function App() {
const name = "this is my name"
return (
<div className="App">
<Son name={name} hello="uuuu" />
</div>
)
}
tips : 特殊 Prop - children
children 相当于 Vue 的默认插槽。
function Son(props) {
return (
<div>
this is Son
<div>{props.children}</div>
</div>
)
}
function App() {
return (
<div className="App">
<Son>
<span>this is children</span>
</Son>
</div>
)
}
父组件传递函数给子组件:
父组件传递一个函数给子组件,子组件调用该函数可修改父组件参数。
2. 使用状态提升实现兄弟组件通信
使用状态提升实现兄弟组件通信,父组件传递状态给子组件,子组件传递修改状态的函数给兄弟组件。
3. 使用 Context 机制实现跨层组件通信
使用 createContext 创建上下文对象,在顶层组件中通过 Provider 提供数据,在需要接收的组件处使用 useContext 获取消费数据。
import { createContext, useContext } from "react"
const MsgContent = createContext()
function ACom(props) {
return (
<div>
this is ACom
<div>
<BCom></BCom>
</div>
</div>
)
}
function BCom(props) {
const getMsg = useContext(MsgContent)
return <div>{getMsg}</div>
}
function App() {
const msg = "this App msg"
return (
<div className="App">
<MsgContent.Provider value={msg}>
<ACom></ACom>
</MsgContent.Provider>
</div>
)
}
useEffect Hook 介绍
useEffect 用于处理组件的副作用,比如发送 Ajax 请求、更改 DOM 等。可根据传递的第二个参数来控制 useEffect 的执行时机。
useEffect(() => {
// Effect
}, [])
- 空数组作为第二个参数:只在组件初始渲染时执行一次。
- 不传第二个参数:组件初始渲染和每次更新都会执行。
- 特定依赖项作为第二个参数:组件初始化和特定依赖项变化时执行。