如何在React

时间:2018-03-14 03:56:28

标签: javascript reactjs dictionary

我有一个.map()函数,我在这里迭代一个数组并渲染元素,如下所示:

      {options.map((option, i) => (
        <TachyonsSimpleSelectOption
          options={options[i]}
          key={i}
          onClick={() => this.isSelected(i)}
          selected={this.toggleStyles("item")}
        />

我正在切换所选元素的状态,如下所示:

isSelected (i) {
    this.setState({ selected: !this.state.selected }, () => { console.log(this.state.selected) })
}

使用switch语句更改样式:

  toggleStyles(el) {
    switch (el) {
      case "item":
        return this.state.selected ? "bg-light-gray" : "";
        break;
    }
  }

然后将我的toggleStyles方法作为道具传递给TachyonsSimpleSelectOption组件的className。

问题

正在为数组中的所有项目切换类,但我只想定位当前单击的项目。

Link to Sandbox.

我在这里做错了什么?

3 个答案:

答案 0 :(得分:1)

您未正确使用selected状态。

在您的代码中,要确定它是否被选中,您取决于该状态,但您没有指定当前选择的项目。

而是保存一个布尔状态,您可以存储当前选择的索引,以便只影响指定的项目。

这可能是一个粗略的答案,但我希望我能给你一些想法。

你的渲染上的

{options.map((option, i) => (
  <TachyonsSimpleSelectOption
    options={options[i]}
    key={i}
    onClick={() => this.setState({ selectedItem: i })}
    selected={this.determineItemStyle(i)}
   />
))}

将确定selected道具价值的函数:

determineItemStyle(i) {
  const isItemSelected = this.state.selectedItem === i;
  return isItemSelected ? "bg-light-gray" : "";
}

希望这个答案会给你一些尤里卡时刻

答案 1 :(得分:0)

你没有说明切换了哪个元素。由于状态只有一个布尔值selected,因此它不知道选择了哪个元素。

为此,请将isSelected功能更改为:

isSelected (i) {
  this.setState({ selected: i }, () => { 
    console.log(this.state.selected) })
}

现在,React状态知道选择了索引i上的项目。用它来现在切换你的课程。

如果您想存储多个选定项目,则需要存储索引数组而不是仅存储一个索引

答案 2 :(得分:0)

TachyonsSimpleSelectOption.js:

import React from 'react';

class Option extends React.Component {
  render() {
    const { selected, name } = this.props;
    return(
       <h1 
        onClick={() => this.props.onClick()}
        style={{backgroundColor: selected ? 'grey' : 'white'}}
       >Hello {name}!</h1>
    )
  }
}
export default Option;

index.js:

import React from "react";
import { render } from "react-dom";
import TachyonsSimpleSelectOption from "./TachyonsSimpleSelectOption";

const options = ["apple", "pear", "orange"];

const styles = {
  selected: "bg-light-gray"
};

class Select extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      open: false,
      selected: []
    };

    this.handleClick = this.handleClick.bind(this);
    this.handleBlur = this.handleBlur.bind(this);
    this.isSelected = this.isSelected.bind(this);
  }

  handleBlur() {
    this.toggleMenu(close);
  }

  handleClick(e) {
    this.toggleMenu();
  }

  toggleMenu(close) {
    this.setState(
      {
        open: !this.state.open
      },
      () => {
        this.toggleStyles("menu");
      }
    );
  }

  toggleStyles(el, index) {
    switch (el) {
      case "menu":
        return this.state.open ? "db" : "dn";
        break;
      case "item":
        const { selected } = this.state;
        return selected.indexOf(index) !== -1;
        break;
    }
  }

  isSelected(i) {
    let { selected } = this.state;
    if (selected.indexOf(i) === -1) {
      selected.push(i);
    } else {
      selected = selected.filter(index => index !== i);
    }
    this.setState({ selected});
  }

  render() {
    const { options } = this.props;
    return (
      <div
        className="flex flex-column ba"
        onBlur={this.handleBlur}
        tabIndex={0}
      >
        <div className="flex-row pa3" onClick={this.handleClick}>
          <span className="flex-grow-1 w-50 dib">Title</span>
          <span className="flex-grow-1 w-50 dib tr">^</span>
        </div>
        <div className={this.toggleStyles("menu")}>
          {options.map((option, i) => (
            <TachyonsSimpleSelectOption
              name={options[i]}
              key={i}
              onClick={() => this.isSelected(i)}
              selected={this.toggleStyles("item", i)}
            />
          ))}
        </div>
      </div>
    );
  }
}

render(<Select options={options} />, document.getElementById("root"));

Link to Sandbox.