从react16到react18,react-router v4 到 v6,这个react全家桶发生了很多变化。
关于 Vite 还是 Webpack
个人觉得目前工作中还是首选 webpack,vite 开发体验也就好一点点,但是生态上还有些缺陷,比如前阵子尝试qiankun发现是不支持vite的,仅支持 webpack。
React
在v16.8就加入了 react hooks,以前因为有些问题不会解决而坚持用 Class Component,短短一年时间,已经是目前主流代码风格了,本人现在也是十分后悔,不过上手也是十分简单。另外提一下热门hooks库ahooks
const [count, setCount] = useState(0)
useEffect(() => {
console.log('componentDidMount')
}, [])
类组件也有不少变化
新增了getDerivedStateFromProps生命周期,目的是根据props的改变去更新state
static getDerivedStateFromProps(props, state) {
return { // 返回的是state更新内容
total: props.count + state.other
}
}
丢弃了 componentWillMount,componentWillReciveProps, componentWillUpdate 生命周期,官方不建议使用,坚持使用需要加 UNSAFE_ 前缀
React Router v6
基本上全变了,react-router也进行了hooks改造,而且原本的一些组件都有很大改变。
Switch, Redirect 这些组件都没有了
现在是用 Routes + Route
<Routes>
<Route path="/" element={<Dashboard />}>
<Route
path="messages"
element={<DashboardMessages />}
/>
<Route path="tasks" element={<DashboardTasks />} />
</Route>
<Route path="about" element={<AboutPage />} />
</Routes>
或者使用hooks useRoutes
function App() {
let element = useRoutes([
{
path: "/",
element: <Dashboard />,
children: [
{
path: "messages",
element: <DashboardMessages />,
},
{ path: "tasks", element: <DashboardTasks /> },
],
},
{ path: "team", element: <AboutPage /> },
]);
return element;
}
Redirect 重定向替代方案
<Route path="*" element={<Navigate to="/" replace />} />
或者自定义重定向组件
const Redirect: FC<RedirectProps> = ({ to }) => {
const navigate = useNavigate();
useEffect(() => {
navigate(-1);
console.error('Bad route');
});
return null;
};
<Route path="*" element={<Redirect to="/" />} />
以前需要通过withRouter将route属性传入组件props中,现在可以通过各种hooks去获取你需要的信息,比如location
let location = useLocation();
如果需要代码中进行跳转
let navigate = useNavigate();
// 跳转到特定页面
navigate("../success", { replace: true });
// 返回上一个
navigate(-1)
outlet是v6的新组件,可以当做以前的switch,他需要用在父组件中,当子组件的路由匹配时候,outlet就会显示对应的内容。
比如下面代码,在进入应用时候,就会显示Layout组件,当 url 为/home的时候,<Outlet />就是会显示Home组件
function Layout() {
return (
<div className="layout">
<div>this is a header</div>
<div className="content">
<Outlet />
</div>
</div>
);
}
function App() {
return (
<Routes>
<Route path="/" element={<Layout />}>
<Route path="home" element={<Home />} /></Route>
</Routes>
);
}
Recoil
使用 recoil 作为新的状态管理工具,风格上更符合 react hooks,易用性上也是吊打 redux,相比 mobx 那种为了政治正确尬改函数也更加优雅。
就像是一个可以跨组件 useState 那样简单,只需要声明一个作为 store 的 atom
const fontSizeState = atom({ key: 'fontSizeState', default: 14,});function Home() { const [fontSize] = useRecoilState(fontSizeState); return ( <div> <div style={{ fontSize: `${fontSize}px` }}> fontSize is {fontSize} </div> <ChangeFontSize /> </div> );}function ChangeFontSize() { const[fontSize, setFontSize] = useRecoilState(fontSizeState); const addFontSize = () => { setFontSize((oldFontSize) => oldFontSize + 1); }; return ( <div> <button type="button" onClick={addFontSize}> 增大字号 </button> </div> );}