React.js中如何复用函数与useState变量 避免重复复制粘贴代码?
React重复逻辑复用解决方案
你遇到的这类状态、处理函数、计算逻辑完全一致的重复场景,在React中可以通过以下两种方案实现复用,无需复制粘贴代码:
方案1:自定义Hook(仅复用逻辑首选)
自定义Hook是React专门用于抽离可复用状态逻辑的方案,你可以把所有重复的逻辑封装到一个以use开头的函数中,需要使用时直接调用即可,每次调用都会生成完全独立的状态,互不干扰。
封装自定义Hook代码示例
import { useState } from 'react'; // 替换为你实际引用图表组件的路径 import { Line, Bar, Pie, Radar, Doughnut, Scatter, PolarArea, Bubble } from 'chart.js/react'; const useChart = () => { const [title, setTitle] = useState(""); const [state, setState] = useState({}); const [getId, setGetId] = useState([]); const [info, setInfo] = useState([]); const clickCheck = title => e => { setState({ ...state, [title]: [e.currentTarget.value], }); // 修正原代码直接修改state的不规范写法,所有state修改走setter函数 const newIdArr = [...getId, e.currentTarget.id]; setGetId(newIdArr.length > 2 ? [] : newIdArr); }; const axis = getId.length >= 2 ? [ info.map(i => i[getId[0]]).slice(1), info.map(i => i[getId[1]]).slice(1), ] : [[], []]; const chartData = { labels: axis[0], datasets: [ { label: title, data: axis[1], backgroundColor: [ "rgba(255, 99, 132, 1)", "rgba(54, 162, 235, 1)", "rgba(255, 206, 86, 1)", "rgba(75, 192, 192, 1)", "rgba(153, 102, 255, 1)", "rgba(255, 159, 64, 1)", ], }, ], }; const chartArray = [ <Line key="o" data={chartData} options={{ responsive: true, maintainAspectRatio: false }} />, <Bar key="p" data={chartData} options={{ responsive: true, maintainAspectRatio: false }} />, <Pie key="q" data={chartData} options={{ responsive: true, maintainAspectRatio: false }} />, <Radar key="r" data={chartData} options={{ responsive: true, maintainAspectRatio: false }} />, <Doughnut key="s" data={chartData} options={{ responsive: true, maintainAspectRatio: false }} />, <Scatter key="t" data={chartData} options={{ responsive: true, maintainAspectRatio: false }} />, <PolarArea key="u" data={chartData} options={{ responsive: true, maintainAspectRatio: false }} />, <Bubble key="v" data={chartData} options={{ responsive: true, maintainAspectRatio: false }} />, ]; return { title, setTitle, state, setState, getId, setGetId, info, setInfo, clickCheck, axis, chartData, chartArray } }
组件内使用示例
const YourBusinessComponent = () => { // 生成第一组图表逻辑 const { title: title1, setTitle: setTitle1, info: info1, setInfo: setInfo1, clickCheck: clickCheck1, chartArray: chartArray1 } = useChart(); // 生成第二组图表逻辑 const { title: title2, setTitle: setTitle2, info: info2, setInfo: setInfo2, clickCheck: clickCheck2, chartArray: chartArray2 } = useChart(); // 需要更多组逻辑直接重复调用useChart即可 return ( // 你的业务UI代码,按需使用上面返回的状态和方法 ) }
方案2:封装独立组件(逻辑+UI一起复用首选)
如果每组逻辑对应的UI结构也完全一致,你可以直接把逻辑和UI一起封装成独立的业务组件,需要多少组就渲染多少个组件即可。
封装组件示例
const ChartGroup = () => { // 直接复用上面定义的useChart const { title, setTitle, info, setInfo, clickCheck, chartArray } = useChart(); return ( <div className="chart-group-wrap"> {/* 替换为你每组图表对应的UI结构 */} <input value={title} onChange={(e) => setTitle(e.target.value)} placeholder="输入图表标题" /> <div className="chart-list"> {chartArray.map(ChartItem => ChartItem)} </div> </div> ) }
组件内使用示例
const YourBusinessComponent = () => { return ( <div> <ChartGroup /> <ChartGroup /> {/* 需要多少组就渲染多少个ChartGroup */} </div> ) }
注意事项
- 原代码中直接修改state(
getId = [])的写法不符合React规范,所有state的修改都必须通过对应的setter函数实现,避免出现状态不同步的问题,上述代码已经修正了该问题 - 可以给自定义Hook或封装的组件增加props参数,支持传入个性化配置(比如自定义背景色、图表尺寸等),灵活适配不同场景的需求
内容的提问来源于stack exchange,提问作者Somi
相关产品推荐
相关产品推荐

