【问题标题】:Click on radio button and display the corresponding value inside the radio button as selected in react js material UI design单击单选按钮并在单选按钮内显示相应的值,如在 react js 材料 UI 设计中选择的那样
【发布时间】:2020-09-24 22:08:46
【问题描述】:

我是 React js Material UI 设计的新手。 我想要的是如下所示。

如果我单击了第一个单选按钮,其值 1 应显示在所选单选按钮内。

我只能使用以下实现独立单选按钮。

import React from 'react';
import { withStyles } from '@material-ui/core/styles';
import { green } from '@material-ui/core/colors';
import Radio from '@material-ui/core/Radio';

const GreenRadio = withStyles({
 root: {
  color: green[400],
  '&$checked': {
  color: green[600],
  },
},
checked: {},
})((props) => <Radio color="default" {...props} />);

export default function RadioButtons() {
  const [selectedValue, setSelectedValue] = React.useState('a');

  const handleChange = (event) => {
   setSelectedValue(event.target.value);
  };

  return (
   <div>
    <Radio
    checked={selectedValue === 'a'}
    onChange={handleChange}
    value="a"
    name="radio-button-demo"
    inputProps={{ 'aria-label': 'A' }}
  />
  <Radio
    checked={selectedValue === 'b'}
    onChange={handleChange}
    value="b"
    name="radio-button-demo"
    inputProps={{ 'aria-label': 'B' }}
  />
  <GreenRadio
    checked={selectedValue === 'c'}
    onChange={handleChange}
    value="c"
    name="radio-button-demo"
    inputProps={{ 'aria-label': 'C' }}
  />
  <Radio
    checked={selectedValue === 'd'}
    onChange={handleChange}
    value="d"
    color="default"
    name="radio-button-demo"
    inputProps={{ 'aria-label': 'D' }}
  />
  <Radio
    checked={selectedValue === 'e'}
    onChange={handleChange}
    value="e"
    color="default"
    name="radio-button-demo"
    inputProps={{ 'aria-label': 'E' }}
    size="small"
  />
</div>
);
}

如何获取所选按钮内的值?

【问题讨论】:

  • 我认为这是不可能的,因为Radio 组件使用了 input type="radio" HTML 原生元素。对于你想要的,你需要创建一个像收音机但呈现自定义元素的组件

标签: reactjs material-ui


【解决方案1】:

这有点小技巧,但是 (s)css 和自定义 data elements 的组合可以解决问题。首先,我添加了一个带有字段值的自定义属性(data-test,你显然会比我有更好的名字):

  <Radio
    checked={selectedValue === "e"}
    onChange={handleChange}
    value="e"
    data-test="e"
    color="default"
    name="radio-button-demo"
    inputProps={{ "aria-label": "E" }}
    size="small"
  />

然后我用了这个scss

.Mui-checked {
  position: relative;

  .MuiSvgIcon-root + .MuiSvgIcon-root {
    opacity: 0;
  }

  &::after {
    content: attr(data-test);
    position: absolute;
    top: 4px;
  }
}

Mui-checked 是类MaterialUI 在元素被检查时给出。因为这是一个span,它可以有伪元素。所以基本上我正在访问自定义数据元素并将content 属性设置为它的值。 .MuiSvgIcon-root.PrivateRadioButtonIcon-layer-6 是在checkbox 中间获取默认点的选择器。这被隐藏了。

您必须对样式进行一些调整以适应您的用例,您可以找到一个演示 here

编辑: 这是css,我还更新了选择器以提高它的稳定性:

.App {
  font-family: sans-serif;
  text-align: center;
}

.Mui-checked {
  position: relative;
}

.Mui-checked::after {
  content: attr(data-test);
  position: absolute;
  top: 4px;
}

.MuiSvgIcon-root + .MuiSvgIcon-root {
  opacity: 0;
}

【讨论】:

  • 如何在 Material UI 设计中实现 css?你能检查一下吗,codesandbox.io/s/falling-dream-qj551?file=/src/App.tsx
  • 我将 css 添加到我的答案中。您的问题是您将 scss 添加到 css 文件中。这现在是纯 css,您可以在那里复制。
  • 但是如果我尝试将这个 css 粘贴到 App.tsx 文件本身中,按照材料 ui 模式,它显示 attr is not defined 。 codesandbox.io/s/falling-dream-qj551?file=/src/App.tsx
  • 您是否将data-test 属性添加到 Radio 组件?
  • 是的,我已经添加了。你可以在我提供的链接中看到
【解决方案2】:

这是我想出的解决方案:我从 ButtonBase 构建了一个自定义组件。
它工作正常,但不如@Gh05d 聪明。另一方面,它避免编写全局样式或挖掘 Material-UI 的内部结构:

const useStyle = makeStyles((theme) => ({
  root: {
    margin: 4,
    borderRadius: "50%"
  },
  checked: {
    height: 30,
    width: 30,
    backgroundColor: "#0a2",
    color: "#fff",
    borderRadius: "50%",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    fontWeight: "bold"
  },
  notchecked: {
    height: 26,
    width: 26,
    borderRadius: "50%",
    border: "2px solid #00000066",
    color: "#ffffff00"
  }
}));

function MyButton(props) {
  const { children, checked, ...rest } = props;

  const classes = useStyle();

  return (
    <ButtonBase {...rest} className={classes.root}>
      <div className={clsx(checked ? classes.checked : classes.notchecked)}>
        {children}
      </div>
    </ButtonBase>
  );
}

function App() {
  const [selectedValue, setSelectedValue] = React.useState("a");

  const handleChange = (letter) => (event) => {
    setSelectedValue(letter);
  };

  return (
    <div>
      <MyButton
        checked={selectedValue === "a"}
        onClick={handleChange("a")}
        value="a"
      >
        A
      </MyButton>
      <MyButton
        checked={selectedValue === "b"}
        onClick={handleChange("b")}
        value="b"
      >
        B
      </MyButton>
      <MyButton
        checked={selectedValue === "c"}
        onClick={handleChange("c")}
        value="c"
      >
        C
      </MyButton>
    </div>
  );
}

【讨论】:

  • 通向罗马的方式很多 ;-)
猜你喜欢
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-26
  • 2011-12-13
  • 1970-01-01
相关资源
最近更新 更多