React全家桶近版本知识更新

262 阅读2分钟

从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
    }
}

丢弃了 componentWillMountcomponentWillReciveProps, 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>  );}