<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Hello World</title> <script src="https://unpkg.com/react@18/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <!-- Don't use this in production: --> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> function MyApp() { return <h1>Hello, world!</h1>; } const container = document.getElementById('root'); const root = ReactDOM.createRoot(container); root.render(<MyApp />); </script> <!-- Note: this page is a great way to try React but it's not suitable for production. It slowly compiles JSX with Babel in the browser and uses a large development build of React. Read this section for a production-ready setup with JSX: https://reactjs.org/docs/add-react-to-a-website.html#add-jsx-to-a-project In a larger project, you can use an integrated toolchain that includes JSX instead: https://reactjs.org/docs/create-a-new-react-app.html You can also use React without JSX, in which case you can remove Babel: https://reactjs.org/docs/react-without-jsx.html --> </body> </html> 其风格是JS与DOM混合在一起,以JS为主; 或者说是将DOM嵌入了JS,同时DOM中可以通过大括号引用JS react中文学习网 https://zh-hans.react.dev/learn react API https://zh-hans.react.dev/reference/react babeljs https://babeljs.io/ 这种混合写法由babeljs后台翻译为浏览器可识别的JS语法 |
npx create-react-app react1 xt@xuetu:/opt/wks/nodejs$ npx create-react-app react1 npm startnpm start Starts the development server. npm run build Bundles the app into static files for production. npm test Starts the test runner. npm run eject Removes this tool and copies build dependencies, configuration files and scripts into the app directory. If you do this, you can’t go back! We suggest that you begin by typing: cd react1 npm start |
import { useState } from 'react'; function MyButton({ count, onClick }) { return ( <button onClick={onClick}> 点了 {count} 次 </button> ); } export default function MyApp() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <div> <h1>共同更新的计数器</h1> <MyButton count={count} onClick={handleClick} /> <MyButton count={count} onClick={handleClick} /> </div> ); } const [count, setCount] = useState(0); 这行代码写在哪个组件中,变量的作用域就会贯穿该组件及该组件下的所有组件 注意组件函数的参数是一对花括号{} 这些参数是组件的属性,称为 prop,即参数变量以组件的属性名称命名, 其值就是组件属性的值 注意click事件传递的是函数, 像下面这样的情况,并不是传递的函数,而是函数的调用,会出问题,比如无限循环 <Square value={squares[0]} onSquareClick={handleClick(0)} /> 如果想在调用函数时传递参数,可以使用下面的方式 <Square value={squares[0]} onSquareClick={() => handleClick(0)} /> useState除了可设置数字外,还可以设置布尔值,数组 export default function Board() { const [xIsNext, setXIsNext] = useState(true); const [squares, setSquares] = useState(Array(9).fill(null)); function handleClick(i) { const nextSquares = squares.slice(); if (xIsNext) { nextSquares[i] = "X"; } else { nextSquares[i] = "O"; } setSquares(nextSquares); setXIsNext(!xIsNext); } return ( //... ); } |
export default function Square() { return ( <> <button className="square">X</button> <button className="square">X</button> </> ); } React 组件必须返回单个 JSX 元素,不能像两个按钮那样返回多个相邻的 JSX 元素。 要解决此问题,可以使用 Fragment(<> 与 </>)包裹多个相邻的 JSX 元素 |
|
https://zh-hans.react.dev/learn/your-first-component React 组件是一段可以 使用标签进行扩展 的 JavaScript 函数。 允许你将标签、CSS 和 JavaScript 组合成自定义“组件”,即 应用程序中可复用的 UI 元素 定义函数 使用 function Profile() { } 定义名为 Profile 的 JavaScript 函数。 export default function Profile() { return ( <img src="https://i.imgur.com/MK3eW3Am.jpg" alt="Katherine Johnson" /> ) } React 组件是常规的 JavaScript 函数,但 组件的名称必须以大写字母开头,否则它们将无法运行! 导出组件 export default 前缀是一种 JavaScript 标准语法(非 React 的特性) ![]() 使用组件 function Profile() { return ( <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" /> ); } export default function Gallery() { return ( <section> <h1>了不起的科学家</h1> <Profile /> <Profile /> <Profile /> </section> ); } ![]() |
import Gallery from './Gallery.js'; export default function App() { return ( <Gallery /> ); } function Profile() { return ( <img src="https://i.imgur.com/QIrZWGIs.jpg" alt="Alan L. Hart" /> ); } export default function Gallery() { return ( <section> <h1>了不起的科学家们</h1> <Profile /> <Profile /> <Profile /> </section> ); } import Gallery from './Gallery'; 无论是 './Gallery.js' 还是 './Gallery',在 React 里都能正常使用,只是前者更符合 原生 ES 模块。 从同一文件中导出和导入多个组件 为了减少在默认导出和具名导出之间的混淆,一些团队会选择只使用一种风格(默认或者具名), 或者禁止在单个文件内混合使用。这因人而异,选择最适合你的即可! import Gallery from './Gallery.js'; import { Profile } from './Gallery.js'; export default function App() { return ( <Profile /> ); } export function Profile() { return ( <img src="https://i.imgur.com/QIrZWGIs.jpg" alt="Alan L. Hart" /> ); } export default function Gallery() { return ( <section> <h1>了不起的科学家们</h1> <Profile /> <Profile /> <Profile /> </section> ); } ![]() |
|
|
|
网页是构建在 HTML、CSS 和 JavaScript 之上的。 但随着 Web 的交互性越来越强,逻辑越来越决定页面中的内容。 JavaScript 控制着 HTML 的内容! JSX and React 是相互独立的 东西。但它们经常一起使用, 但你 可以 单独使用它们中的任意一个, JSX 是一种语法扩展,而 React 则是一个 JavaScript 的库。 下面是HTML <h1>海蒂·拉玛的待办事项</h1> <img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" class="photo" > <ul> <li>发明一种新式交通信号灯 <li>排练一个电影场景 <li>改进频谱技术 </ul> 下面是JSX export default function TodoList() { return ( <> <h1>海蒂·拉玛的待办事项</h1> <img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" className="photo" /> <ul> <li>发明一种新式交通信号灯</li> <li>排练一个电影场景</li> <li>改进频谱技术</li> </ul> </> ); } 差异 JSX 规则 1. 只能返回一个根元素 - 这个空标签被称作 Fragment。React Fragment 允许你将子元素分组,而不会在 HTML 结构中添加额外节点。 2. 标签必须闭合 3. 使用驼峰式命名法给 所有 大部分属性命名! - 需要用 strokeWidth 代替 stroke-width。 - 由于 class 是一个保留字,所以在 React 中需要用 className 来代替。 |
![]() export default function TodoList() { return ( <ul style={ { backgroundColor: 'black', color: 'pink' } }> <li>Improve the videophone</li> <li>Prepare aeronautics lectures</li> <li>Work on the alcohol-fuelled engine</li> </ul> ); } const person = { name: 'Gregorio Y. Zara', theme: { backgroundColor: 'black', color: 'pink' } }; export default function TodoList() { return ( <div style={person.theme}> <h1>{person.name}'的待办事项</h1> <img className="avatar" src="https://i.imgur.com/7vQD0fPs.jpg" alt="Gregorio Y. Zara" /> <ul> <li>优化视屏电话</li> <li>准备航空学课程</li> <li>研究乙醇燃料引擎</li> </ul> </div> ); } |
util.js export function getImageUrl(person, size = 's') { return ( 'https://i.imgur.com/' + person.imageId + size + '.jpg' ); } App.js import { getImageUrl } from './utils.js'; function Avatar({ person, size }) { return ( <img className="avatar" src={getImageUrl(person)} alt={person.name} width={size} height={size} /> ); } export default function Profile() { return ( <div> <Avatar size={100} person={ { name: 'Katsuko Saruhashi', imageId: 'YfeOqp2' } } /> <Avatar size={80} person={ { name: 'Aklilu Lemma', imageId: 'OKS67lh' } } /> <Avatar size={50} person={ { name: 'Lin Lanying', imageId: '1bX5QH6' } } /> </div> ); } props 是 组件的唯一参数! function Avatar({ person, size }) { // ... } 这种语法被称为 “解构”,等价于于从函数参数中读取属性: function Avatar(props) { let person = props.person; let size = props.size; // ... } ![]() |
![]() |
当你将内容嵌套在 JSX 标签中时,父组件将在名为 children 的 prop 中接收到该内容。 例如,下面的 Card 组件将接收一个被设为 <Avatar /> 的 children prop 并将其包裹在 div 中渲染: import Avatar from './Avatar.js'; function Card({ children }) { return ( <div className="card"> {children} </div> ); } export default function Profile() { return ( <Card> <Avatar size={100} person={ { name: 'Katsuko Saruhashi', imageId: 'YfeOqp2' } } /> </Card> ); } |
要传递 props,请将它们添加到 JSX,就像使用 HTML 属性一样。 要读取 props,请使用 function Avatar({ person, size }) 解构语法。 你可以指定一个默认值,如 size = 100,用于缺少值或值为 undefined 的 props 。 你可以使用 <Avatar {...props} /> JSX 展开语法转发所有 props,但不要过度使用它! 像 <Card><Avatar /></Card> 这样的嵌套 JSX,将被视为 Card 组件的 children prop。 Props 是只读的时间快照:每次渲染都会收到新版本的 props。 你不能改变 props。当你需要交互性时,你可以设置 state。 |
|