javascript - 在 React 中创建多选按钮网格

标签 javascript reactjs

size side bar

我正在尝试在 React.js 中实现具有上述外观的按钮网格。

预期行为

单击每个按钮时都会切换 SizeButton 上的 selected 类。

上图中选中的按钮是带有“X”的按钮。

实际发生的情况

单击每个按钮时不会切换SizeButton上的selected类。

我认为实现这一点的方式是一个包含许多单独按钮组件的包装组件。包装组件将包含与每个按钮的状态相关的状态信息。

上图是我所期待的,但实际上并没有发生。

SizeSideBar.js

class SizeSideBar extends Component {
    constructor(props) {
        super(props);

        this.state = {
            query: ''
        }

        this.setSize = this.setSize.bind(this);
    }

    setSize(size) {
        this.setState({
            query: size.toUpperCase(),
        }, () => {
            if (this.state.query.length > 0) {
                this.props.history.push(`?size=${size.toUpperCase()}`)
            }
        })
    }

    render() {
        return (
            <div>
                <h3>Size</h3>
                <hr />
                <div>
                    <SizeButton size="x" setSize={this.setSize} />
                    <SizeButton size="xxs" setSize={this.setSize} />
                    <SizeButton size="xs" setSize={this.setSize} />
                    <SizeButton size="s" setSize={this.setSize} />
                    <SizeButton size="m" setSize={this.setSize} />
                    <SizeButton size="l" setSize={this.setSize} />
                    <SizeButton size="xl" setSize={this.setSize} />
                    <SizeButton size="xxl" setSize={this.setSize} />
                    <SizeButton size="2xl" setSize={this.setSize} />
                    <SizeButton size="3xl" setSize={this.setSize} />
                    <SizeButton size="4xl" setSize={this.setSize} />
                </div>
            </div>
        )
    }
}

SizeButton.js

const SizeButton = (props) => {
    const { size, setSize } = props

    const selectedSize = getPageQueries(window.location.search).size
    const isSelected = selectedSize === size

    return (
        <button
            id="sizeButton"
            className={isSelected ? 'selected' : ''}
            onClick={() => {
                setSize(size);
            }}
        >
            {size.toUpperCase()}
        </button>
    )
}

getPageQueries()

export const getPageQueries = (url) => {
    const arr = url.slice(1).split(/&|=/); // remove the "?", "&" and "="
    let params = {};

    for(let i = 0; i < arr.length; i += 2){
       const key = arr[i], value = arr[i + 1];
       params[key] = value ; // build the object = { limit: "10", page:"1", status:"APPROVED" }
    }

    return params;
};

最佳答案

让每个按钮管理它自己的选择状态,单击它会设置它自己的颜色。

class SizeButton extends React.Component {

  state = {
    isSelected: false,
  }

  setSelected = () => {
    this.setState({
      isSelected: !this.state.isSelected
    })
  }

  render() {
    const { size, setSize } = this.props;
    return (
      <button
        id="sizeButton"
        className={this.state.isSelected ? 'selected' : ''}
        onClick={() => {
          this.setSelected();
          setSize(size);
        }}
      >
        {size.toUpperCase()}
      </button>
    )
  }
}

创建一个大小对象数组,例如 {size: 'X', isSelected: false } ,并循环遍历该数组检查是否 isSelected是真的。

state = {
 query: [
   {size: 'X', isSelected: false },
   {size: 'xxs', isSelected: false },
   {size: 'xs', isSelected: false }
 ],
}

然后渲染尺寸,例如

render() {
  return (
    <div>
      <h3>Size</h3>
      <hr />
      <div />
      {this.state.queries.map((button, key) => (
        <SizeButton
          key={key}
          size={button.size}
          isSelected={button.isSelected}
          setSize={this.setSize}
        />
      ))}
    </div>
  );
}


const SizeButton = (props) => {
const { size, setSize, isSelected } = props

  return (
      <button
        id="sizeButton"
        className={isSelected ? 'selected' : ''}
        onClick={() => {
            setSize(size);
        }}
      >
        {size.toUpperCase()}
      </button>
   )
}

演示

.selected {
  border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<div id="root"></div>

<script type="text/babel">

class SizeButton extends React.Component {

  state = {
    isSelected: false,
  }

  setSelected = () => {
    this.setState({
      isSelected: !this.state.isSelected
    })
  }

  render() {
    const { size, setSize } = this.props;
    return (
      <button
        id="sizeButton"
        className={this.state.isSelected ? 'selected' : ''}
        onClick={() => {
          this.setSelected();
          setSize(size);
        }}
      >
        {size.toUpperCase()}
      </button>
    )
  }
}

class App extends React.Component {

  state = {

  }

  setSize = (size) => {

  }

  render() {
    return (
      <div>
        <h3>Size</h3>
        <hr />
        <div>
          <SizeButton size="x" setSize={this.setSize} />
          <SizeButton size="xxs" setSize={this.setSize} />
          <SizeButton size="xs" setSize={this.setSize} />
          <SizeButton size="s" setSize={this.setSize} />
          <SizeButton size="m" setSize={this.setSize} />
          <SizeButton size="l" setSize={this.setSize} />
          <SizeButton size="xl" setSize={this.setSize} />
          <SizeButton size="xxl" setSize={this.setSize} />
          <SizeButton size="2xl" setSize={this.setSize} />
          <SizeButton size="3xl" setSize={this.setSize} />
          <SizeButton size="4xl" setSize={this.setSize} />
        </div>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));

</script>

关于javascript - 在 React 中创建多选按钮网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56463225/

相关文章:

javascript - 没有花括号的 if 语句上的多个语句

javascript - ASP.Net Core 回发后如何保持选项卡处于事件状态

javascript - sleep /等待/暂停 JavaScript

javascript - 如何使用传递给 reducer 的事件对象验证 reducer 内的单选按钮?

javascript - 在不模糊的情况下调整 Canvas 图像的大小

javascript - 使用 jQuery 触发相邻表格单元格中的链接

javascript - 在 2 个 React DOM 之间传递数据

javascript - Reactjs 中获取错误处理的问题

javascript - react : How to iterate through state and output to jsfiddle page

reactjs - 在 onClick 函数内调用更新函数时 useState 不会重新渲染