You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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)

问题原因:

  1. 返回值错误:JS中逗号运算符只会返回最后一个表达式的值,这里实际只返回local,其他变量都被丢弃。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 07:37:19