React18记账本实战:路由配置全解析

React18 路由案例:记账本实现指南

路由配置与基础框架搭建

使用 react-router-dom v6 配置路由结构,在 main.jsxApp.jsx 中初始化路由:

import { createBrowserRouter, RouterProvider } from 'react-router-dom';
const router = createBrowserRouter([
  { path: '/', element: <Home /> },
  { path: '/detail', element: <Detail /> },
  { path: '/edit', element: <EditRecord /> }
]);
function App() {
  return <RouterProvider router={router} />;
}

页面组件设计与布局

创建记账本核心页面组件:

  • Home.jsx 显示账单列表和统计摘要
  • Detail.jsx 展示单笔账单详情
  • EditRecord.jsx 处理新增/编辑账单的表单
// Home.jsx 示例结构
const Home = () => {
  const [records, setRecords] = useState([]);
  return (
    <div className="app-container">
      <MonthFilter />
      <BillSummary />
      <RecordList records={records} />
      <FloatButton link="/edit" />
    </div>
  );
};

路由跳转与参数传递

实现带参数的路由跳转:

// 跳转到编辑页并传递ID
<Link to={`/edit?id=${record.id}`}>编辑</Link>

// 在编辑组件获取参数
import { useSearchParams } from 'react-router-dom';
const [searchParams] = useSearchParams();
const recordId = searchParams.get('id');

数据管理方案

推荐使用 Context API + useReducer 管理全局状态:

// RecordContext.js
export const RecordContext = createContext();
export function RecordProvider({children}) {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <RecordContext.Provider value={{state, dispatch}}>
      {children}
    </RecordContext.Provider>
  );
}

表单处理与验证

实现带验证的账单表单:

const EditRecord = () => {
  const { dispatch } = useContext(RecordContext);
  const formik = useFormik({
    initialValues: { amount: '', category: 'food' },
    validationSchema: Yup.object({
      amount: Yup.number().required().positive()
    }),
    onSubmit: values => {
      dispatch({ type: 'ADD_RECORD', payload: values });
    }
  });
  return <form onSubmit={formik.handleSubmit}>{/* 表单字段 */}</form>;
};

响应式布局优化

使用 CSS Grid 实现多设备适配:

.record-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1rem;
}
@media (max-width: 768px) {
  .app-container {
    padding: 0 10px;
  }
}

性能优化技巧

实现路由懒加载和 Suspense:

const EditRecord = lazy(() => import('./EditRecord'));
const router = createBrowserRouter([
  {
    path: '/edit',
    element: (
      <Suspense fallback={<Loading />}>
        <EditRecord />
      </Suspense>
    )
  }
]);

完整功能扩展建议

  1. 增加本地存储持久化
useEffect(() => {
  localStorage.setItem('records', JSON.stringify(state.records));
}, [state.records]);
  1. 添加账单分类筛选功能
const filteredRecords = records.filter(
  record => selectedCategory === 'all' 
    || record.category === selectedCategory
);
  1. 集成图表库实现数据可视化
import { PieChart } from 'recharts';
<PieChart data={categoryData}>
  <Pie dataKey="value" data={data} />
</PieChart>

BbS.okane060.info/PoSt/1121_447091.HtM
BbS.okane061.info/PoSt/1121_776224.HtM
BbS.okane062.info/PoSt/1121_038036.HtM
BbS.okane063.info/PoSt/1121_067127.HtM
BbS.okane065.info/PoSt/1121_125645.HtM
BbS.okane066.info/PoSt/1121_483819.HtM
BbS.okane067.info/PoSt/1121_933754.HtM
BbS.okane068.info/PoSt/1121_117688.HtM
BbS.okane069.info/PoSt/1121_073206.HtM
BbS.okane070.info/PoSt/1121_767014.HtM
BbS.okane060.info/PoSt/1121_594822.HtM
BbS.okane061.info/PoSt/1121_697247.HtM
BbS.okane062.info/PoSt/1121_409098.HtM
BbS.okane063.info/PoSt/1121_182589.HtM
BbS.okane065.info/PoSt/1121_563442.HtM
BbS.okane066.info/PoSt/1121_615591.HtM
BbS.okane067.info/PoSt/1121_814597.HtM
BbS.okane068.info/PoSt/1121_326899.HtM
BbS.okane069.info/PoSt/1121_756217.HtM
BbS.okane070.info/PoSt/1121_572891.HtM
BbS.okane071.info/PoSt/1121_637858.HtM
BbS.okane072.info/PoSt/1121_162622.HtM
BbS.okane073.info/PoSt/1121_900321.HtM
BbS.okane074.info/PoSt/1121_307893.HtM
BbS.okane075.info/PoSt/1121_571427.HtM
BbS.okane076.info/PoSt/1121_894079.HtM
BbS.okane077.info/PoSt/1121_200121.HtM
BbS.okane078.info/PoSt/1121_526348.HtM
BbS.okane079.info/PoSt/1121_417944.HtM
BbS.okane080.info/PoSt/1121_619837.HtM
BbS.okane071.info/PoSt/1121_914061.HtM
BbS.okane072.info/PoSt/1121_022586.HtM
BbS.okane073.info/PoSt/1121_617012.HtM
BbS.okane074.info/PoSt/1121_498616.HtM
BbS.okane075.info/PoSt/1121_222003.HtM
BbS.okane076.info/PoSt/1121_929564.HtM
BbS.okane077.info/PoSt/1121_498596.HtM
BbS.okane078.info/PoSt/1121_322191.HtM
BbS.okane079.info/PoSt/1121_654743.HtM
BbS.okane080.info/PoSt/1121_037963.HtM
BbS.okane071.info/PoSt/1121_442870.HtM
BbS.okane072.info/PoSt/1121_113686.HtM
BbS.okane073.info/PoSt/1121_417256.HtM
BbS.okane074.info/PoSt/1121_055139.HtM
BbS.okane075.info/PoSt/1121_652468.HtM
BbS.okane076.info/PoSt/1121_783097.HtM
BbS.okane077.info/PoSt/1121_493570.HtM
BbS.okane078.info/PoSt/1121_713304.HtM
BbS.okane079.info/PoSt/1121_858785.HtM
BbS.okane080.info/PoSt/1121_675023.HtM
BbS.okane071.info/PoSt/1121_362891.HtM
BbS.okane072.info/PoSt/1121_724103.HtM
BbS.okane073.info/PoSt/1121_188729.HtM
BbS.okane074.info/PoSt/1121_818553.HtM
BbS.okane075.info/PoSt/1121_611050.HtM
BbS.okane076.info/PoSt/1121_366415.HtM
BbS.okane077.info/PoSt/1121_186799.HtM
BbS.okane078.info/PoSt/1121_093424.HtM
BbS.okane079.info/PoSt/1121_508593.HtM
BbS.okane080.info/PoSt/1121_836462.HtM
BbS.okane071.info/PoSt/1121_826280.HtM
BbS.okane072.info/PoSt/1121_249746.HtM
BbS.okane073.info/PoSt/1121_083376.HtM
BbS.okane074.info/PoSt/1121_133952.HtM
BbS.okane075.info/PoSt/1121_602278.HtM
BbS.okane076.info/PoSt/1121_830217.HtM
BbS.okane077.info/PoSt/1121_092935.HtM
BbS.okane078.info/PoSt/1121_281033.HtM
BbS.okane079.info/PoSt/1121_861775.HtM
BbS.okane080.info/PoSt/1121_861522.HtM
BbS.okane071.info/PoSt/1121_458307.HtM
BbS.okane072.info/PoSt/1121_878386.HtM
BbS.okane073.info/PoSt/1121_675186.HtM
BbS.okane074.info/PoSt/1121_036990.HtM
BbS.okane075.info/PoSt/1121_133928.HtM
BbS.okane076.info/PoSt/1121_642578.HtM
BbS.okane077.info/PoSt/1121_823086.HtM
BbS.okane078.info/PoSt/1121_653346.HtM
BbS.okane079.info/PoSt/1121_362135.HtM
BbS.okane080.info/PoSt/1121_669643.HtM

#牛客AI配图神器#

全部评论

相关推荐

不愿透露姓名的神秘牛友
11-20 10:05
点赞 评论 收藏
分享
11-07 16:07
深圳大学 运营
前端飞升:学长,阿里不是卡双非吗,我深也能去吗
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务