【问题标题】:How do I set state to toggle a boolean value that sits inside an array of JSON object?如何设置状态以切换位于 JSON 对象数组中的布尔值?
【发布时间】:2020-03-17 06:04:26
【问题描述】:

我今天被困在这个问题上,我尝试了几种可能的解决方案,但都没有解决这个问题。

这是我为团队资料页面创建的翻牌效果。当用户点击个人资料卡时,它会翻转卡片以在背面显示更多信息。我目前设置的方式是在触发 onClick 时一次性翻转所有卡片,而不是单个卡片。我知道通过这样做我需要设置 isTrue 的当前状态以从 JSON 对象呈现布尔值,并且我尝试了几种我能想到的可能的方法,但没有继承。

如果有人能帮助我学习/理解如何解决这个问题,我将不胜感激!

这里是简化的示例代码:

JSON 对象:

data: [
  { id: 1, isTrue: false },
  { id: 2, isTrue: false },
  { id: 3, isTrue: false},   
  ...
]

反应组件:

import exampleData from 'data.js'
class App extends Component {
  constructor () {
    super()
    this.state = {
       isTrue: //I need to set the current state of isTrue to render from exampleData, but couldn't figure out how to do it.//
    }
    this.handleToggle = this.handleToggle.bind(this);
  }
  handleToggle (e) {
    e.preventDefault();
    this.setState(prevState => ({
      isTrue: !prevState.isTrue
    }))
  }
render() {
  return(
        <div className="App">
         {exampleData.data.map((obj) => {
           return <ReactCardFlip isTrue={this.state.isTrue}/>
             <button onClick={handleToggle}>Flip the card</div>
           </ReactCardFlip>
          })
        </div>
    );
  }
}
export default App;

【问题讨论】:

  • 您将单个状态映射到 exampleData 中的所有对象。您的状态不能是单个 True/False。每个对象都必须有一个 True/False 并翻转触发 onClick 的那个对象的状态。

标签: javascript arrays json reactjs state


【解决方案1】:

您需要将externalData 存储在组件的状态中。使用map 渲染此列表并将当前点击的卡片传递给toggle 方法。在此之后,您可以根据单击的元素更改状态。请参见下面的示例:

import exampleData from 'data.js'

class App extends Component {
  constructor () {
    super()
    this.state = {
       cards: [],
    }
    this.handleToggle = this.handleToggle.bind(this);
  }

  componentDidMount() {
    this.state.setState({ cards: exampleData });
  }

  handleToggle (card) {
    this.setState(prevState => ({
      cards: prevState.cards.map(prevCard => {
        if (prevCard.id === card.id) {
          return {
            id: prevCard.id,
            isTrue: !prevCard.isTrue
          }
       }

       return prevCard;
    })}));
  }

  render() {
    return (
      <div className="App">
       {this.state.data.map((card) => {
         return (
           <ReactCardFlip isTrue={card.isTrue}>
             <button onClick={() => this.handleToggle(card)}>Flip the card</button>
           </ReactCardFlip>
         )
       })}
      </div>
    );
  }
}
export default App;

【讨论】:

  • 嘿,非常感谢您回答我的问题。这非常有帮助,并引导我解决问题。干杯!
【解决方案2】:

主要是每个项目都应该有自己的isTure

所以单一状态isTrue无法满足你的需求。

两种方式:

  • exampleDatastate
  • isTure => arrIsTrue 对应exampleData 中的每一项

data: [
  { id: 1, isTrue: false },
  { id: 2, isTrue: false },
  { id: 3, isTrue: false},   
  ...
]

这些数据可以放在state

喜欢后:this.state = { exampleData: exampleData.data }

所以render 可以是&lt;ReactCardFlip isTrue={obj.isTrue}/&gt;

handleToggle 也应该获得当前切换索引到之后:

<div className="App">
  {this.state.exampleData.map((obj, index) => {
    return <ReactCardFlip key={index} isTrue={this.state.isTrue}/>
      <button onClick={() => handleToggle(index)}>Flip the card</div>
    </ReactCardFlip>
  })
</div>

然后在handleToggle成为:

handleToggle (index) {
  const exampleData = this.state.exampleData
  exampleData[index] = !exampleData[index].isTrue
  this.setState({ exampleData: exampleData })
}

毕竟别忘了key

【讨论】:

  • 非常感谢您的帮助。这个解释部分解决了我的问题,并让我注意到我在另一个组件中错误地调用了该函数。我已经解决了这个问题。干杯!
猜你喜欢
  • 2017-10-07
  • 1970-01-01
  • 2018-11-23
  • 2017-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多