基础与demo
子组件
父组件
React组件继承React.component来表示一个React组件注册子组件renderSquare:返回一个Square组件的H5实例的函数template组件返回的Dom:render函数表示此组件返回的DomDom模板中的变量使用单大括号{ }来规定JS解析部分,使用<>标签对来包裹domNode父子组件传值在子组件注册函数中,使用key=value来为子组件实例注入一个数据。事件绑定onClick={function...},function可以在return前定义复杂的fun构造函数子组件必须调用一次super作为开头,来执行一次父组件的构造函数state:this.setState函数来改变state值,通过这个方法的改变会被React捕获以更新视图事件代理事件作为一个props传入,子组件事件调用父组件转来的函数计算属性在render函数return之前可以计算需要的属性v-for使用map方法生成一个数据数组映射的reactRenderDom数组,用filter进行过滤v-if<div>{key?value1:value2}</div>v-modle自己反向实现一个input->state:class直接在className/style后面使用js+模板字符串VuexRudux生命周期钩子useEffect(fun...)通用附效应钩子watchuseEffect第二个参数props.name监听以执行回调destroyedusrEffect可以return一个fun作为组件注销时的回调
refrender中标签的ref={name}与vue相同,但是不可用于函数组件,他们没有实例,只能用于class或dom。routerreact-routerslot插销:props.children可以获取到父元素调用此组件时标签包裹的children部分。这可以作为Context的一种替代方案,当这个共享状态只有极个别的跨级组件需要使用时使用插销在父元素渲染对应内容而非将其暴露为公共状态。
文档
元素渲染
下列代码会把名味ID=root的H5节点作为根节点,将element渲染其中。
React元素为不可变对象。它代表了某个时刻的UI。
更新UI的唯一方式是将其传入ReactDom.render();
更新时通过diff对比新旧dom,而不是通过逻辑来改变,可以消灭一整类的bug。
组件&props
官方解释:类似于JS函数,接收任意的入参,来表示页面展示内容的React元素。
- React组件函数/类,接收唯一的参数props,返回/render一个React元素。
- React元素可以使用用户自定义的组件
- JSX中组件必须以大写字母开头,小写标签会被认为是原生的div标签
- React严格规定单项数据流,不支持非纯函数作为组件,props必须是只读的。
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
State&生命周期
- 使用class代替function,每次更新此组件对应的ReactDom,都会创建一个仅对应一个dom实例的class实例,这使得可以使用state和生命周期(和Vue一个道理)
- 在constructor中,接收props并super一次props来调用父类的构造函数增强此实例。然后在this上挂在一个state作为私有的状态集并可以在此时初始化。
- 使用this.setState来通知React更新对应的视图
- 需要注意的:类似于GUI线程与Vue的更新,state与props也可能是异步更新,不要依赖他们来更新下一个状态,因为他们的执行时间点可能不可预测。可以将setState接收一个函数来返回你真正需要的结果对象。(不太理解为什么改成函数就解决了?)
生命周期
- 生命周期
- 挂载
mount:组件第一次被渲染进DOM中。称为挂载 - 卸载
unmount:DOM中的组件被删除。称为卸载
- 挂载
- 钩子函数
- componentDidMount():当组件已经被渲染成dom后执行
- componentWillUnmount():当组件被销毁之前
事件处理
- JSX中使用一个{function}来处理函数,而非传统HTML的字符串。
- React中不能通过return false的方式阻止默认事件,需要在函数中调用e.preventDefault来阻止。
- 注意在onClick等的回调中,如果是一个函数名而不是一个运行了此函数的箭头函数,需要注意此函数运行时的this是没有被绑定的,undefined。
- 这种箭头函数会导致每次渲染此组件的实例时都会创建新的函数。当这个函数作为props传递给下级会造成额外的重新渲染(函数并没有改变,但是由于创建了新的函数而使得子组件以为值改变了,不过谁会把一个匿名的无用函数作为props呢?)
- 或者定义函数时使用fn=()=>{}来使用箭头函数绑定this在父域可以解决这个问题。
- 传递参数可以在绑定时使用bind或者使用一个父级的箭头函数通过参数传递来获取,对应两种绑定的方法
- React的封装事件对象e可以当做参数传递,但是箭头函数的写法e必须手动显式的传递,bind则不需要。
条件渲染&列表渲染-->计算属性思维
在render函数的return之前可以定义变量来计算一些复杂的JSX结果。
例如利用if来选择react元素来进行条件渲染或者使用map来映射数组对应的列表元素。
- &&写法可以轻易而简洁的代替if语法
{ a>0 && <img/> }- js中 && 左侧条件为true则返回右侧部分,左侧为false则返回false。
- 三元运算符也是条件渲染的好选择。
- 让render返回一个null来实现
v-if - React中使用map来映射循环渲染,也需要key值,原理与Vue相同;
- key不需要全局唯一,但是同级兄弟节点必须唯一。
杂记
- 改变对象的副本,再替换新旧对象,而不是直接操作对象属性
- 简化复杂功能,例如回溯等
- 更易捕获数据的改变(感觉没有Vue3的proxy聪明啊)
- 确定在React中何时渲染(!!!暂留有问题)
- 你可以安全的再JSX中插入用户输入,ReactDom会在渲染之前对其转义来防止XSS
- JSX表示对象:Bable会把JSX转译成一个
React.createElement的函数调用,这个函数会执行一些检查后将其转变为一个对象。包含type+props(className...),称其为React元素。 - 处理表单中使用event.target.name+<input name=''/>来区分多个input,在setState中使用[name]计算属性名称来对应name与key值。