react
更适合入门 react 的学习,因为本人没有正儿八经的 react 的项目经验。 之前因为 react 太难了从入门到放弃,后来因为疫情期间参与公司 react+ts 直播项目,打酱油再次入门 react,随着公司技术转向 react 开始入门 react。
对比 vue
,react
更加接近原生的用法。长时间的 vue
一把嗦,都忘记原生的要怎么写了。react
能够在 vue
和 js
找出相似点。所以入门很简单,放弃更容易,秒秒钟的事。
写法:和写原生的 html 差不多,因为 JSX 语法上更接近 JavaScript 而不是 HTML,所以 React DOM 使用 camelCase(小驼峰命名)来定义属性的名称,而不使用 HTML 属性名称的命名约定(例如,JSX 里的 class 变成了 className,而 tabindex 则变为 tabIndex。)用到了变量就用 {} 把变量包起来。每个 JSX 元素都是调用 React.createElement() 的语法糖。
例如:
const element = ( <> <h1>Hello!{name}</h1> <h2>Good to see you here.</h2> </> ); 复制代码
<></> 这里指的是一个空标签,因为只能有一个“根” DOM 节点,Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用
ReactDOM.render(),方法里面传入一个要渲染的元素和一个需要挂载到某一个 DOM 节点上的 id
const element = <h1>Hello, world</h1>; ReactDOM.render(element, document.getElementById('root')); 复制代码
React 元素是不可变对象。一旦被创建,你就无法更改它的子元素或者属性。更新 UI 唯一的方式是创建一个全新的元素,并将其传入 ReactDOM.render()。
React 应用只会调用一次 ReactDOM.render(),页面渲染之后,如果我们想要修改 ui,就需要把代码封装到有状态组件中
和 javascript 上面的差不多
// 三目运算 function Greeting() { return ( <div> { isLoggedIn? <UserGreeting />:<GuestGreeting /> } </div> ) } // && 使用 function Greeting() { return ( <div> { isLoggedIn&&isSunseekers? <UserGreeting />:<GuestGreeting /> } </div> ) } 复制代码
循环用列表渲染用 map ,写法和 javascript ,和 vue 一样要指定唯一的 key。变量用 {} 包裹
function NumberList(){ const numbersList = [] return ( <ul> { numbersList.map(item=>( <li key={item}>{item}</li> )) } </ul> ) } 复制代码
和原生的 js 差不多,区别在于 React 事件的命名采用小驼峰式(camelCase),而不是纯小写。使用 JSX 语法时你需要传入一个函数作为事件处理函数(是一个变量),而不是一个字符串
<button onClick={activateLasers}> Activate Lasers </button> 复制代码
给事件传参数一般通过箭头函数
<button onClick={() => Delete(item)}>Delete Row</button> 复制代码
还可以是 bind 的方式,我不喜欢用,我觉得箭头函数方便
354- 一文吃透 React 事件机制原理
有些组件无法提前知晓它们子组件的具体内容,比如通用容器的展示比如说 Loading Dialog Scroll 等等,这时候我们就可以使用组合。这个就像 vue 里面的插槽一样,父组件给子组件传递一段 JSX 或者 DOM 标签
// 子组件 function FancyBorder(props) { return ( <div className={'FancyBorder FancyBorder-' + props.color}> {props.children} // 这里就是插槽,内容由父组件控制,由 props.children 接受到内容 </div> ); } // 父组件 function WelcomeDialog() { return ( <FancyBorder color="blue"> // 传递给子组件的一段内容,作为children 通过prop 传递 <h1 className="Dialog-title"> Welcome </h1> <p className="Dialog-message"> Thank you for visiting our spacecraft! </p> </FancyBorder> ); } 复制代码
通过 props.children 是一种传递的方式,我还可以也是可以直接使用 props 属性进行传值的,传值的方式和是之前一样直接在组件上面传
function App() { return ( <SplitPane left={ <Contacts /> // 给子组件传递一个 left 属性,他的值是一个组件 } right={ <Chat /> } /> ); } 复制代码
enmmmmm ,这么看的话,其实就是 props 传值的类型可以是任意的,基本类型,引用类型,函数,组件
因为我个人在项目中习惯使用函数组件一把嗦,关于 class 组件我就不介绍了。新版中引入了 hook,让函数组件也可有有生命周期,使用起来更加方便。
函数式组件的首字母要大写,小写的函数,不会被当作组件渲染的。函数组件可以接受一个参数 props 表示传进来的数据(所有传进来的数据都用 props 包裹起来了),不限制类型,可以是函数,对象,数组...,有一个返回值,可以被 react 识别并渲染,通常是 jsx 形式。
函数组件是都决不能修改自身的 props,是一个“纯函数”,相同的输入一定是相同的输出
function Avatar(props) { return ( <img className="Avatar" src={props.user.avatarUrl} alt={props.user.name} /> ); } 复制代码
数据是向下流动的,不管是父组件或是子组件都无法知道某个组件是有状态的还是无状态的,并且它们也并不关心它是函数组件还是 class 组件。
如果项目是 react+ts 结合的话,可以使用 FC 类型来声明,FC 是 FunctionComponent 的简写, 这个类型定义了默认的 props(如 children)以及一些静态属性(如 defaultProps)
import React from 'react'; /** * 声明Props类型 */ export interface MyComponentProps { className: string; style: React.CSSProperties; } export const MyComponent:FC<MyComponentProps> = props=>{ return <div>hello react</div>; } export const MyComponent1:FC<MyComponentProps> = {className,style}=>{ // 参数结构 return <div>hello react</div>; } 复制代码
相当于
import React from 'react'; /** * 声明Props类型 */ export interface MyComponentProps { className: string; style: React.CSSProperties; } export function MyComponent(props:MyComponentProps){ return <div>hello react</div>; } 复制代码
FC 类型来声明和直接用函数有什么区别呢?
In most cases it makes very little difference which syntax is used, but you may prefer the more explicit nature of React.FunctionComponent. 最后一句话,大多数情况下普通函数的形式就够了,如果想要更精准的 TypeScript 类型推断,就用 React.FC
具体使用什么,可以看个人习惯和团队代码风格。当我们直接使用 FC 无法满足需求,这时候就使用函数组件(具体的场景没遇到过
函数式组件与类组件有何不同? => 推荐看(里面详细说了 hook 陈旧值的起因和解决方案
函数式组件与类组件在线区别 demo
React 组件设计实践总结 01 - 类型检查
简单说就是:函数式组件捕获了渲染所使用的值,不会获取到过新的数据
在 React 中 props 是不可变(immutable)的,所以他们永远不会改变。然而,this 而且永远是可变(mutable)的。
事实上,这就是类组件 this 存在的意义。React 本身会随着时间的推移而改变,以便你可以在渲染方法以及生命周期方法中得到最新的实例
所以如果在请求已经发出的情况下我们的组件进行了重新渲染,this.props 将会改变。showMessage 方法从一个“过于新”的 props 中得到了 user。这也就是常说的闭包陈旧的问题,其实并不是闭包陈旧,而是它本身就是这样的
函数式组件中想要渲染最新的值,那就在变化的时候在执行一次一样的操作。函数式组件捕获了渲染所使用的值这种写法是对的。
如果你能够很好的理解函数与闭包的知识,在学习react的时候可以看到很多不一样的东西。完美的避开某些坑
设计好的 ui 进行整个页面的简单布局
根据 ui 划分组件层级
确定 ui 完整的最小颗粒化
整理好理解划分好数据流的流动方向
代码更多地是给人看的。当你开始构建更大的组件库时,你会意识到这种代码模块化和清晰度的重要性。并且随着代码重用程度的加深,你的代码行数也会显著地减少。:),少一行代码,就减少一个 bug 出现的可能性
原文链接,会保持一直更新,建议关注原文,最新更新