我的应用程序有两个用于 Select 选项的字段,我想设置这两个字段之间的依赖关系.

在一个字段中,用户可以 Select 支付系统(‘VISA’或‘MASTER’),根据这个 Select ,不同的值(1000美元、3000美元、5000美元或2000美元、4000美元、8000美元)应该出现在另一个字段中.

请看下面的文件

export const pay: Pay[] = [
  {
    name: 'visa',
    bitrates: [
      { name: '1000$', value: 1000 },
      { name: '3000$', value: 3000 },
      { name: '5000$', value: 5000 },
    ],
  },
  {
    name: 'master',
    bitrates: [
      { name: '2000$', value: 2000 },
      { name: '4000$', value: 4000 },
      { name: '8000$', value: 8000 },
    ],
  },
];

接下来,我有三个组件:一个是两个 Select 的公共组件,另一个是两个 Select 的组件. 对于Select字段,我使用Radix库https://www.radix-ui.com/primitives/docs/components/select.但不管是什么库,我都想了解如何根据PaySistemSelect组件中的值更改PriceSelect组件中的值的原理 看看下面

CommonOptions.tsx

export function CommonOptions() {
  return (
    <div>
      <PaySistemSelect />
      <PriceSelect />
    </div>
  );
}

PaySistemSelect.tsx

export function PaySistemSelect() {
  return (
    <Select.Root>
      <Select.Trigger>
        <Select.Value placeholder="Select pay sistem" />
      </Select.Trigger>
      <Select.Content>
        <Select.Viewport>
          <Select.Item key="" value="" />
          {/* {listWithPaySistem.map((res) => ( */}
          <Select.Item
            // key={res.id}
            value="Something"
          >
            {/* <Select.ItemText>{res.name}</Select.ItemText> */}
          </Select.Item>
          {/* ))} */}
        </Select.Viewport>
      </Select.Content>
    </Select.Root>
  );
}

PriceSelect.tsx

export function PriceSelect() {
  return (
    <Select.Root>
      <Select.Trigger>
        <Select.Value placeholder="Select price" />
      </Select.Trigger>
      <Select.Content>
        <Select.Viewport>
          <Select.Item key="" value="" />
          {/* {listWithPrice.map((res) => ( */}
          <Select.Item
            // key={res.id}
            value="Something"
          >
            {/* <Select.ItemText>{res.name}</Select.ItemText> */}
          </Select.Item>
          {/* ))} */}
        </Select.Viewport>
      </Select.Content>
    </Select.Root>
  );
}

推荐答案

要展开Artyom Ganev‘S comment,您需要使用REACT的状态和props 将选定的支付系统值从CommonOptions父组件传递到PaySistemSelectPriceSelect组件.它将允许PriceSelect基于PaySistemSelect中 Select 的支付系统动态更新其选项.

首先,在CommonOptions组件中维护所选支付系统的状态.每当 Select 新的支付系统并向下传递到PaySistemSelectPriceSelect时,该状态将被更新.

import React, { useState } from 'react';
import { PaySistemSelect } from './PaySistemSelect';
import { PriceSelect } from './PriceSelect';
import { pay } from './payData'; // Assuming payData is the file with your `pay` array

export function CommonOptions() {
  const [selectedPaySystem, setSelectedPaySystem] = useState('');

  return (
    <div>
      <PaySistemSelect
        setSelectedPaySystem={setSelectedPaySystem}
      />
      <PriceSelect
        selectedPaySystem={selectedPaySystem}
      />
    </div>
  );
}

修改PaySistemSelect以通过props接受setSelectedPaySystem函数. Select 付款系统时,使用此功能更新父系统的状态.它使用Radix,这里是Select component来创建用于 Select 支付系统和相应价格选项的菜单.

import React from 'react';
import * as Select from '@radix-ui/react-select';

export function PaySistemSelect({ setSelectedPaySystem }) {
  return (
    <Select.Root onValueChange={setSelectedPaySystem}>
      <Select.Trigger>
        <Select.Value placeholder="Select pay system" />
      </Select.Trigger>
      <Select.Content>
        <Select.Viewport>
          <Select.Item key="visa" value="visa">
            <Select.ItemText>Visa</Select.ItemText>
          </Select.Item>
          <Select.Item key="master" value="master">
            <Select.ItemText>Master</Select.ItemText>
          </Select.Item>
        </Select.Viewport>
      </Select.Content>
    </Select.Root>
  );
}

从那里,PriceSelect需要根据所选的支付系统过滤可用选项.它将接受selectedPaySystem作为props :

import React from 'react';
import * as Select from '@radix-ui/react-select';
import { pay } from './payData'; // Assuming this is your data file

export function PriceSelect({ selectedPaySystem }) {
  const options = pay.find(p => p.name === selectedPaySystem)?.bitrates || [];

  return (
    <Select.Root>
      <Select.Trigger>
        <Select.Value placeholder="Select price" />
      </Select.Trigger>
      <Select.Content>
        <Select.Viewport>
          {options.map((option) => (
            <Select.Item key={option.value} value={option.name}>
              <Select.ItemText>{option.name}</Select.ItemText>
            </Select.Item>
          ))}
        </Select.Viewport>
      </Select.Content>
    </Select.Root>
  );
}

这应该允许您通过将状态提升到它们的公共父级并将其作为props 传递下来,从而在sibling 组件之间共享状态.


at the moment, when opening a page with the PaySistemSelect and PaySistemSelect fields, these fields are empty (even if something was selected earlier). How can I set them to default values?
I see that Select.Root has defaultValue and value in its parameters. How can they be applied and what should be written there?

You should be able to use the defaultValue property of Select.Root in Radix UI.
However, if you want to restore selections based on user actions or saved preferences beyond the initial load, you might transition to using value and manage the state changes through user interactions or effects.

value使组件由Reaction控制,这意味着您可以通过props 在外部管理其状态.如果需要在初始渲染后以编程方式更新选定值,请使用该选项.


此解决方案(defaultValue)仅适用于具有"visa"的初始情况.如果我 Select "master",则PriceSelect字段变为空.

如果在 Select "master"之后,PriceSelect字段变为空,则这可能是由于PriceSelect组件没有在初始呈现之后基于新 Select 的支付系统来更新其缺省值的机制.当你从"visa"切换到"master"时,PriceSelect需要动态调整其选项,并可能设置一个与"master"支付系统相对应的新的默认值.

try 使用React的效果钩(useEffect)来监听selectedPaySystemprops 中的变化.这样,您就可以在PriceSelect内设置一个确定 Select 哪个值的本地状态.该方法将组件转换为由Reaction控制,这意味着您将使用valueprops 而不是defaultValue来显式控制选定的选项.

import React, { useEffect, useState } from 'react';
import * as Select from '@radix-ui/react-select';
import { pay } from './payData'; // Assuming this is your data file

export function PriceSelect({ selectedPaySystem }) {
  const options = pay.find(p => p.name === selectedPaySystem)?.bitrates || [];
  const [selectedPrice, setSelectedPrice] = useState(options.length > 0 ? options[0].name : '');

  // Update the selected price when the selected payment system changes
  useEffect(() => {
    setSelectedPrice(options.length > 0 ? options[0].name : '');
  }, [selectedPaySystem, options]);

  return (
    <Select.Root value={selectedPrice} onValueChange={setSelectedPrice}>
      <Select.Trigger>
        <Select.Value placeholder="Select price" />
      </Select.Trigger>
      <Select.Content>
        <Select.Viewport>
          {options.map((option) => (
            <Select.Item key={option.value} value={option.name}>
              <Select.ItemText>{option.name}</Select.ItemText>
            </Select.Item>
          ))}
        </Select.Viewport>
      </Select.Content>
    </Select.Root>
  );
}

通过在Select.Root上使用valueprops 并通过状态(selectedPrice)管理所 Select 的值,PriceSelect成为受控组件.这意味着它的当前价值始终由react 状态驱动,允许根据用户交互或外部变化(如切换支付系统)进行动态更新.

Reactjs相关问答推荐

如何使用react-router-dom导航到网页中的其他路由?

react -在选项中 Select 我想要显示和图像.但当我 Select 该选项时,我希望控件仅显示该选项的文本部分

NextJS如何正确保存添加到购物车中的产品会话

React:关于useEffect钩子如何工作的困惑

获取更改后的状态值

在ReactJS的monaco编辑器中添加美人鱼语法

为什么react日历时间轴项Renderprops 不能与useState挂钩一起使用?

在 React 中是否有任何理由要记住 Redux 操作创建者?

Mui Datepicker 设置了错误的日期

获取 不能显示为 的后代.错误,但不太确定如何构建我的代码以避免此警告

我可以在加载器函数中多次 fetch() 并使用一次 useloaderdata() 提取它吗?

未捕获的运行时错误:对象作为 React 子项无效

React Native 背景动画反转

React 测试库 - 如何断言异步函数之间的中间状态?

如何在不重新加载页面的情况下加载新添加的数据?

AWS 全栈应用程序部署教程构建失败

错误:无效挂钩调用.钩子只能在函数组件的主体内部调用.使用 next/router 时

如何使用react 路由将 url 参数限制为一组特定的值?

react-admin useGetIdentity 只返回全名,id 未定义 头像未定义

a.active 类在导入 x.scss 文件时有效,但在使用 x.module.scss 时无效