【问题标题】:RadioGroup will not select when onChange is set that uses useState hook当设置了使用 useState 钩子的 onChange 时,RadioGroup 不会选择
【发布时间】:2019-11-06 16:29:49
【问题描述】:

我有一个非常好用的 RadioGroup。当我将该 RadioGroup 移动到它自己的功能中时——“选择”不起作用。就好像组件无法完全重新渲染一样。当我附加一个使用状态挂钩的onChange 事件时,就会发生这种情况。您可以在这里看到,收音机 1 和 2 运行良好。收音机 3 和 4 没有。

CodeSandbox Material UI RadioBox Example

这是我正在使用的组件。未包装到函数中的 RadioGroup 运行良好。那个——它不“选择”。这意味着黑点不会出现在选择单选按钮中。

function Demo(props) {
  const [inputs, setInputs] = useState({});

  const handleInputChange = event => {
    event.persist();
    setInputs(inputs => ({
      ...inputs,
      [event.target.name]: event.target.value
    }));

    console.debug(`${event.target.name}: ${event.target.value}`);
  };

  const NotWorking = props => {
    return (
      <RadioGroup aria-label="two" name="two" row onChange={handleInputChange}>
        <FormControlLabel
          value="3"
          control={<Radio color="primary" />}
          label="3"
          labelPlacement="end"
        />
        <FormControlLabel
          value="4"
          control={<Radio />}
          label="4"
          labelPlacement="end"
        />
      </RadioGroup>
    );
  };

  return (
    <React.Fragment>
      <RadioGroup aria-label="one" name="one" row onChange={handleInputChange}>
        <FormControlLabel
          value="1"
          control={<Radio color="primary" />}
          label="1"
          labelPlacement="end"
        />
        <FormControlLabel
          value="2"
          control={<Radio />}
          label="2"
          labelPlacement="end"
        />
      </RadioGroup>
      <NotWorking />
    </React.Fragment>
  );
}

我们将不胜感激。

【问题讨论】:

  • 附注- 两者都会触发 handleInputChange 事件 ....

标签: reactjs material-ui


【解决方案1】:

您的包装组件必须接受onChange 处理程序作为道具,以及inputs。此外,您可以将其移到父组件之外以获得更好的可读性:

const NotWorking = props => {
    return (
      <RadioGroup aria-label="two" name="two" row onChange={props.onChange}>
        <FormControlLabel
          value="3"
          control={<Radio color="primary" />}
          label="3"
          labelPlacement="end"
        />
        <FormControlLabel
          value="4"
          control={<Radio />}
          label="4"
          labelPlacement="end"
        />
      </RadioGroup>
    );
  };


function Demo(props) {
  const [inputs, setInputs] = useState({});

  const handleInputChange = event => {
    event.persist();
    setInputs(inputs => ({
      ...inputs,
      [event.target.name]: event.target.value
    }));

    console.debug(`${event.target.name}: ${event.target.value}`);
  };

  return (
    <React.Fragment>
      <RadioGroup aria-label="one" name="one" row onChange={handleInputChange}>
        <FormControlLabel
          value="1"
          control={<Radio color="primary" />}
          label="1"
          labelPlacement="end"
        />
        <FormControlLabel
          value="2"
          control={<Radio />}
          label="2"
          labelPlacement="end"
        />
      </RadioGroup>
      <NotWorking onChange={handleInputChange} />
    </React.Fragment>
  );
}

【讨论】:

  • 我按照你的建议做了,见codesandbox.io/s/… 并且事件没有触发......但单选框确实呈现。但我需要它来触发事件......
  • 它不触发是什么意思?我可以在控制台中看到输出。
  • 我添加了第三个组件,完全按照您的建议。把它移到了外面。称之为清晰。单选值是 5 和 6。如果您查看控制台,它不会触发 onChange 事件...codesandbox.io/s/…
  • 啊,对不起,在NotWorking 组件中应该是onChange={props.onChange} 而不是onChange={props.handleInputChange}。我已经更新了答案。
【解决方案2】:

您实际上并没有在任何地方使用您的输入。您需要指定值。否则你会得到一个不受控制的无线电组(它应该在这两种情况下都可以工作,但显然由于某种原因我还没有弄清楚)。

但是,您可以通过以下方式使其工作并且能够通过查看状态来判断选择了什么:

function Demo(props) {
  const [inputs, setInputs] = useState({});

  const handleInputChange = event => {
    event.persist();
    setInputs(inputs => ({
      ...inputs,
      [event.target.name]: event.target.value
    }));

    console.debug(`${event.target.name}: ${event.target.value}`);
  };

  const NotWorking = props => {
    return (
      <RadioGroup aria-label="two" name="two" value={inputs.two || ''} row onChange={handleInputChange}>
        <FormControlLabel
          value="3"
          control={<Radio color="primary" />}
          label="3"
          labelPlacement="end"
        />
        <FormControlLabel
          value="4"
          control={<Radio />}
          label="4"
          labelPlacement="end"
        />
      </RadioGroup>
    );
  };

  return (
    <React.Fragment>
      <RadioGroup aria-label="one" name="one" value={inputs.one || ''} row onChange={handleInputChange}>
        <FormControlLabel
          value="1"
          control={<Radio color="primary" />}
          label="1"
          labelPlacement="end"
        />
        <FormControlLabel
          value="2"
          control={<Radio />}
          label="2"
          labelPlacement="end"
        />
      </RadioGroup>
      <NotWorking />
    </React.Fragment>
  );
}

export default Demo;

Demo

【讨论】:

  • 这也有效。我打开了一个 MUI 错误,由于它不是错误而被关闭。但作者 (oliviertassinari) 确实说过:“提示:新组件实例 => 重新挂载 => 重置本地状态。” github.com/mui-org/material-ui/issues/18237
  • 谢谢,我最终选择了下面的答案,因为输入 onChange={props.onChange} 比必须知道在“输入”中使用的确切值更容易且更不容易出错。是inputs.one,inputs.two吗?只需输入 onChange={props.onChange.} 更容易
猜你喜欢
  • 2019-08-07
  • 2019-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-23
  • 2020-06-10
  • 2020-01-31
  • 2019-08-15
相关资源
最近更新 更多