如何在嵌套数组中设置State

时间:2019-05-10 11:01:49

标签: javascript reactjs

我正在练习一个React并试图建立Arya的杀戮清单。我玩转并实现了一些功能,双击该功能可以改变一个人。在状态下,我有数组<---的数组(人员列表),我想将setState设置为此数组。

我尝试使用三元运算符,该运算符假定将状态从false更改为true以及相反。但这是行不通的。

以下是我尝试实现的解决方案的代码示例:

class App extends React.Component {
  state = {
    toKill: [
      { name: 'Cersei Lannister',
        formDouble: false
      },
      { name: 'Ser Ilyn Payne',
        formDouble: false
      },
      { name: 'The Mountain',
        formDouble: false
      },
      { name: 'The Hound',
        formDouble: false
      }
    ], 
  }

doubleClickHandler = (index) => {
    this.setState({
      toKill: this.state.toKill.map(obj =>
        obj[index].formDouble ? false : true)
    })


    // console.log(this.state.toKill[index].formDouble)
    // this.state.toKill[index].formDouble === false ? 
    // this.setState({
    //   [this.state.toKill[index].formDouble]: true
    // }) : this.setState({
    //   [this.state.toKill[index].formDouble]: false
    // })
  }

(...)

        <div>
          {this.state.toKill.map((toKill, index) => {
          return <ToKill 
            double ={() => this.doubleClickHandler(index)}
            formDouble={toKill.formDouble}
            click ={() => this.deleteToKillHandler(index)}
            key={index + toKill.name}
            name={toKill.name}
            cause={toKill.cause}
            img={toKill.img} />
          })}
        </div>

在doubleClickHandler中,您可以看到我尝试实现的功能,但没有用。

这是toKill组件:



const ToKill = (props) => {

  return (
    <div className="hero-card" onDoubleClick={props.double}>
    {props.formDouble !== true? <h1>test</h1> 
      : <>
          <div className="hero-img-container">
            <img 
              src={props.img} 
              alt={props.name}
              className="hero-img"
            />
          </div>
          <div className="hero-desc">
            <h3 className="hero-name">{props.name}</h3>
            <p className="hero-cause">{props.cause}</p>
            <button onClick={props.click}>Delete</button>
          </div>
        </>
  }
    </div>
    )
}

所以我期望的是,一旦我双击某个特定元素(例如“山”),它将向我显示其配置文件,而其余部分将显示<h1>test</h1>

1 个答案:

答案 0 :(得分:5)

您的doubleClickHandler很可能是错误的。据我了解,您只想为单击的单个元素将formDouble设置为true。在这种情况下,doubleClickHandler应该是

doubleClickHandler = (index) => {
    this.setState({
        toKill: this.state.toKill.map((obj, objIndex) =>
            objIndex === index ? {...obj, formDouble: true} : {...obj, formDouble: false})
    })
}

使用以下代码的代码段:

class App extends React.Component {
  state = {
    toKill: [
      { name: "Cersei Lannister", formDouble: false },
      { name: "Ser Ilyn Payne", formDouble: false },
      { name: "The Mountain", formDouble: false },
      { name: "The Hound", formDouble: false }
    ]
  };

  doubleClickHandler = index => {
    this.setState({
      toKill: this.state.toKill.map((obj, objIndex) =>
        objIndex === index
          ? { ...obj, formDouble: true }
          : { ...obj, formDouble: false }
      )
    });
  };

  render() {
    return (
      <div>
        {this.state.toKill.map((toKill, index) => {
          return (
            <ToKill
              double={() => this.doubleClickHandler(index)}
              formDouble={toKill.formDouble}
              click={() => this.deleteToKillHandler(index)}
              key={index + toKill.name}
              name={toKill.name}
              cause={toKill.cause}
              img={toKill.img}
            />
          );
        })}
      </div>
    );
  }
}

const ToKill = props => {
  return (
    <div className="hero-card" onDoubleClick={props.double}>
      {props.formDouble !== true ? (
        <h1>test</h1>
      ) : (
        <React.Fragment>
          <div className="hero-img-container">
            <img src={props.img} alt={props.name} className="hero-img" />
          </div>
          <div className="hero-desc">
            <h3 className="hero-name">{props.name}</h3>
            <p className="hero-cause">{props.cause}</p>
            <button onClick={props.click}>Delete</button>
          </div>
        </React.Fragment>
      )}
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>