如何在React组件间复用从Redux获取的区域变量值?
解决组件间复用Redux数据处理逻辑的问题
问题背景
原本想通过props实现组件间变量复用,但props由接收组件管理,现在需要把从Redux存储的API嵌套数组中处理后的变量值,导出给多个组件使用,避免重复编写相同的find()查询逻辑。
示例组件:RegionButtons.jsx
import React, { useState } from 'react' import { useSelector } from 'react-redux'; import { Box, Fab } from '@mui/material' const RegionButtons = ( { handleNationals, handleState, handleRegionals, handleLocal, selectedIndex }) => { const [selectedRegion, setSelectedRegion] = useState("local"); const data = useSelector((state) => state.level) const wrestling_level = useSelector((state) => data.wrestling_level[selectedIndex]) const nationwide = wrestling_level.Nationwide.find((s) => s.type === "Nationals"); const statewide = wrestling_level.region.find((s) => s.region === "State"); const regionals = wrestling_level.region.find((s) => s.region === "Regionals"); const local = wrestling_level.region.find((s) => s.region === "Local"); return ( <Box className="button-area" > { nationwide && <Fab onClick={handleNationals}> NATIONALS </Fab> } { statewide && <Fab onClick={handleState}> STATE </Fab> } { regionals && <Fab onClick={handleRegionals}> REGIONALS </Fab> } { local && <Fab onClick={handleLocal}> LOCAL </Fab> } </Box> ) } export default RegionButtons
需要复用的重复逻辑
这段从Redux中读取数据并通过find()处理的代码,在多个组件中重复出现:
const data = useSelector((state) => state.level) const wrestling_level = useSelector((state) => data.wrestling_level[selectedIndex]) const nationwide = wrestling_level.Nationwide.find((s) => s.type === "Nationals"); const statewide = wrestling_level.region.find((s) => s.region === "State"); const regionals = wrestling_level.region.find((s) => s.region === "Regionals"); const local = wrestling_level.region.find((s) => s.region === "Local");
已尝试的方法及问题
尝试将逻辑封装到util.js中,但调用后获取的值为undefined:
util.js(原错误版本)
import { useSelector } from 'react-redux'; export function Regions (selectedIndex) { const data = useSelector((state) => state.level) const wrestling_level = useSelector((state) => data.wrestling_level[selectedIndex]) const nationwide = wrestling_level.Nationwide.find((s) => s.type === "Nationals"); const statewide = wrestling_level.region.find((s) => s.region === "State"); const regionals = wrestling_level.region.find((s) => s.region === "Regionals"); const local = wrestling_level.region.find((s) => s.region === "Local"); console.log("nationwide from utils file:", nationwide); // 打印正常 return nationwide, statewide, regionals, local // 这里是错误根源 }
调用方式
import {Regions} from '../../util'; Regions(selectedIndex)
问题原因:
- 返回值错误:JS中逗号运算符只会返回最后一个表达式的值,这里实际只返回
local,其他变量都被丢弃。 - Hook使用违规:
useSelector是React Hook,只能在组件或自定义Hook的顶层调用,普通函数中调用不符合Hook规则。
解决方案
将封装逻辑改为自定义React Hook,并修正返回值格式:
修改后的util.js
import { useSelector } from 'react-redux'; // 自定义Hook必须以use开头,遵循Hook规则 export function useRegions(selectedIndex) { // 优化:一次获取所需的wrestling_level,减少Redux订阅次数 const wrestling_level = useSelector((state) => state.level.wrestling_level[selectedIndex]); // 使用可选链?.避免空值报错,增强健壮性 const nationwide = wrestling_level?.Nationwide?.find(s => s.type === "Nationals"); const statewide = wrestling_level?.region?.find(s => s.region === "State"); const regionals = wrestling_level?.region?.find(s => s.region === "Regionals"); const local = wrestling_level?.region?.find(s => s.region === "Local"); // 返回对象,方便组件解构使用 return { nationwide, statewide, regionals, local }; }
在组件中使用
import React, { useState } from 'react' import { useSelector } from 'react-redux'; import { Box, Fab } from '@mui/material'; import { useRegions } from '../../util'; const RegionButtons = ({ handleNationals, handleState, handleRegionals, handleLocal, selectedIndex }) => { const [selectedRegion, setSelectedRegion] = useState("local"); // 调用自定义Hook,解构需要的变量 const { nationwide, statewide, regionals, local } = useRegions(selectedIndex); return ( <Box className="button-area" > { nationwide && <Fab onClick={handleNationals}> NATIONALS </Fab> } { statewide && <Fab onClick={handleState}> STATE </Fab> } { regionals && <Fab onClick={handleRegionals}> REGIONALS </Fab> } { local && <Fab onClick={handleLocal}> LOCAL </Fab> } </Box> ) } export default RegionButtons
关键说明
- 自定义Hook规则:必须以
use开头,React才能识别并允许在其中使用其他Hook(如useSelector)。 - 返回值格式:返回对象而非逗号分隔的值,组件可以通过解构灵活获取需要的变量。
- 可选链操作:
?.运算符防止wrestling_level或其子属性为undefined时抛出错误,提升代码稳定性。 - 性能优化:合并
useSelector调用,减少对Redux store的订阅次数,提升组件性能。
内容的提问来源于stack exchange,提问作者LOTUSMS
相关产品推荐
相关产品推荐

