序言
- 从技术栈Vue变为React是比较常见的状况,文中就得环节做一个归纳纪录。
- 立即学习培训React的小白开发人员也可以作为参照。
- 文中里面的内容多数为本人遇到的难题或是思索。这当中绝大多数官方网站都是有表明。
Vue到React
文中只纪录最关键,最突出的形象化差别。如果你想要详尽的功能对比,建议大家看本文。
- 假如你用过Vue的3D渲染函数公式和JSX,这个知识点和React是相近的。但在React中这一部分比例比较重。由于Vue大部分时候建议使用模版词法。但注意仅仅类似,JSX编译程序可能并不一样。细分化查询官方网站这儿。
- React不容易全自动替你更新视图,部件内部结构数据信息变更后,必须手动式setState。假如传到子组件的props产生变化,子组件会开启再次3D渲染。
- React里的props比Vue更加灵活。基本上可以看做是Vue的props slot。
疑难问题
引起无限循环
1. 部件上直接启用会开启re-render的思路
export const MyComponent = (props) => {
const [t, setT] = useState(0);
// 每一次部件3D渲染都是会再次走到这里,setState又再次开启部件3D渲染
setT((o) => o 1);
return <h1>{t}</h1>;
};
2. useEffect无依靠时启用re-render的思路(和1相近)
export const MyComponent = (props) => {
const [t, setT] = useState(0);
// 由于无依靠,部件每一次3D渲染进行之后进到useEffect的调整,setState又再次开启部件3D渲染
useEffect(() => {
setT((o) => o 1);
});
return <h1>{t}</h1>;
};
3. 不正确设定props初始值
export const MyComponent = (props) => {
const [t, setT] = useState(0);
// 每一次部件3D渲染都是会再次走到这里,setState又再次开启部件3D渲染
setT((o) => o 1);
return <h1>{t}</h1>;
};
export const MyComponent = (props) => {
const [t, setT] = useState(0);
// 由于无依靠,部件每一次3D渲染进行之后进到useEffect的调整,setState又再次开启部件3D渲染
useEffect(() => {
setT((o) => o 1);
});
return <h1>{t}</h1>;
};
这一点是最隐敝,最容易忽略的,一定要十分谨慎。
export const MyComponent = (props) => {
// arr是一个引用类型,引用类型给予初始值,每一次3D渲染时都赋了一个不一样地址引入。
const { arr = [] } = props;
const [t, setT] = useState(0);
// useEffet会以为props arr出现了改变,因为每次3D渲染都是会进到调整,事实上和状况2一样了
useEffect(() => {
setT((o) => o 1);
}, [arr]);
return <h1>{t}</h1>;
};
函数中取过的值未升级
1. setState异步更新
export const MyComponent = (props) => {
const [t, setT] = useState(0);
useEffect(() => {
setT((o) => o 1);
// setState后立刻同歩获得,获得过的为升级前值
console.log(t, 't'); // 0
}, []);
return <h1>{t}</h1>;
};
2. Hooks闭包圈套
针对setState异步更新里的事例,再去拓展一下,不难发现useState的闭包难题。
export const MyComponent = (props) => {
const [t, setT] = useState(0);
useEffect(() => {
setT((o) => o 1);
// 毕竟是时钟频率难题,就强制推迟实行state获得实际操作,就会发现仍然取不上系统重装后的state
setTimeout(() => {
console.log(t, 't0'); // 0
}, 1000);
}, []);
return <h1>{t}</h1>;
};
- 形成原因:简单讲,事例里的effect会在初次3D渲染完了强制执行,effect函数在实施时建立自已的执行上下文,自变量t由于闭包的主要原因一直存在该执行上下文中,当第二次3D渲染,t升级了,事实上和effect里的t在内存中是两个自变量。若是在依靠页面上添加t,useEffect内部结构会自动升级自变量t。
3. 解决方案
难题1、2的具体缘故和优化解决方案,可参考本文。这儿得出本人常用解决方法。
- 在useEffect中,假如逻辑性容许,能把自变量参与到依靠页面上。例如针对以上事例,假如你只要获得t,而且打印出,就可将其参与到依靠目录。而例子中既要get,还得set。假如参与到依靠目录会引起无限循环
- 应用useRef。useRef建立的自变量根植于部件全部生命期。所以不用担心闭包难题。
容易忽略这个概念
这一部分是自己在细读官方网站后,发觉与我以前了解存有偏差一些定义。
useEffect的消除机会
- 实行下一个 effect 以前,上一个 effect 就已经被消除。即useEffect的调整强制执行前,消除上一次的调整。
export const MyComponent = (props) => {
const [t, setT] = useState(0);
useEffect(() => {
if (t < 5) {
setT((o) => o 1);
}
// 在return的函数中实行消除的思路
return () => {
console.log(t); //打印出了5次,0 1 2 3 4
};
});
return <h1 onClick={() => {}}>{t}</h1>;
};
- 部件卸载掉时一定会启用一次消除。这也就是为什么可以使用依靠为空数组的useEffect取代部件卸载掉的生命周期
JSX针对不同算法设计的处理方式
- 布尔类型、Null 及其 Undefined 可能忽视
// 能够放心大胆写如下所示分辨编码,不用担心true或是undefined被3D渲染到页面中。但要谨慎0和NaN
{t && <h1>{t}</h1>}
- 二维数组能被结构3D渲染,即按序3D渲染二维数组里的每一项
动态组件
如果某个环境下的部件必须动态性3D渲染,能够有两种计划方案。
- 先把部件名取值给一个大写的自变量,务必英文大写,然后使用JSX3D渲染。这儿展现官网事例
import React from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
// 恰当!JSX 种类能是英文大写字母开头自变量。const SpecificStory = components[props.storyType];
return <SpecificStory story={props.story} />;
}
- 直接用createElement方式建立部件,此方法的第一个主要参数可以用正常自变量。因此更新改造官方网站事例。
import React, { createElement } from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
// c为js自变量就可以
const c = components[props.storyType];
return createElement(c, { story: props.story });
}
声明:本文仅供个人学习使用,来源于互联网,本文有改动,本文遵循[BY-NC-SA]协议, 如有侵犯您的权益,请联系本站,本站将在第一时间删除。谢谢你