React18记账本实战:路由配置全解析
React18 路由案例:记账本实现指南
路由配置与基础框架搭建
使用 react-router-dom v6 配置路由结构,在 main.jsx 或 App.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>
)
}
]);
完整功能扩展建议
- 增加本地存储持久化
useEffect(() => {
localStorage.setItem('records', JSON.stringify(state.records));
}, [state.records]);
- 添加账单分类筛选功能
const filteredRecords = records.filter(
record => selectedCategory === 'all'
|| record.category === selectedCategory
);
- 集成图表库实现数据可视化
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


