Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
458 views
in Technique[技术] by (71.8m points)

javascript - 如何使用包装器控制按钮的切换(How to control the toggle of a button using a wrapper)

I'm building a Toggle Button and the specifications tells me that a group of Toggle Buttons should have the behavior to allow only single click( see example ) and multiple clicks( see example ).(我正在构建一个“切换按钮”,规范告诉我一组“切换按钮”应具有仅允许单击( 请参见示例 )和多次单击( 请参见示例 )的行为。)

Multiple click is just fine, since theres not much logic to implement, but the single click is pretty hard to me.(多次单击就可以了,因为没有太多要实现的逻辑,但是单次单击对我来说很难。)

The main idea of using the single click is that if i toggle a button and try to toggle another one, the previous should lost his state of pressed and the clicked one should have it.(使用单击的主要思想是,如果我切换一个按钮并尝试切换另一个按钮,则前一个按钮应失去其pressed状态,而单击的按钮应具有pressed状态。) When pressed is true, the ToggleButton has a different CSS.(当pressed是真实的,切换按钮有不同的CSS。)

This is my toggle button component:(这是我的切换按钮组件:)

const ToggleButton = props => {
  const { onClick, value, ...other } = props;
  const [pressed, setPressed] = useState(true);
  const renderPressedButton = () => {
    setPressed(!pressed);
    if (onClick) {
      onClick();
    }
  };
  return (
    <StyledToggleButton
      className={!pressed ? 'pressed' : null}
      pressed={pressed}
      data-value={value}
      {...other}
      onClick={renderPressedButton}
    />
  );
};

and this is my wrapper(atm i'm only getting the class of what i'm clicking):(这是我的包装器(自动取款机,我只得到我要单击的类):)

const onClickHandler = e => {
  const index = e.target.closest('.pressed');
  // console.log(index);
  // console.log('classe: ', e.target.className);
  if (index) {
    console.log('its pressed!');
  }
};

const ToggleButtonGroup = props => {
  const { ...other } = props;
  return <StyledToggleButtonGroup onClick={onClickHandler} {...other} />;
};

I think i should use Context API or maybe move my renderPressedButton logic to my wrapper.(我认为我应该使用上下文API或将我的renderPressedButton逻辑移到包装器中。)

Anyone has an idea?(有人有主意吗?)

And this is how i plan to use the component:(这就是我计划使用该组件的方式:)

<ToggleButtonGroup singleClick>
     <ToggleButton>One</ToggleButton>
     <ToggleButton>Two</ToggleButton>
</ToggleButtonGroup>
  ask by ncesar translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Lift the state up to ToggleButtonGroup .(将状态提升到ToggleButtonGroup 。)

Maintain a list of toggled indices there and provide a boolean as prop to ToggleButton keeping it completely stateless.(在此处维护一个已切换索引的列表,并为ToggleButton提供布尔值作为道具,以使其保持完全无状态。) By this way, you will be able to control each ToggleButton individually from ToggleButtonGroup based on any click.(通过这种方式,您将能够基于任何单击从ToggleButtonGroup分别控制每个ToggleButton 。)
function ToggleButtonGroup({ singleClick, children }) {
  const [checked, setChecked] = React.useState([]);

  const handleClick = event => {
    // event.target should have your clicked checbox reference
    const index = event.target.dataset.index;

    if (singleClick) {
      setChecked([index]);
    } else {
      if (checked.includes(index)) {
        setChecked(checked.filter(eachIndex => eachIndex !== index));
      } else {
        setChecked([...checked, index]);
      }
    }
  };

  return (
    <div onClick={handleClick}>
      {React.Children.map(children, (child, index) => {
        return React.cloneElement(child, {
          dataIndex: index,
          pressed: checked.includes(index)
        });
      })}
    </div>
  );
}



function ToggleButton({ dataIndex, pressed, ...rest }) {
  return <div data-index={dataIndex} className={!pressed ? 'pressed' : null} {...rest} />;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...