【问题标题】:Struggling to pass an index of an array as props to another component努力将数组的索引作为道具传递给另一个组件
【发布时间】:2021-09-17 15:39:44
【问题描述】:

我正在尝试构建一个应用程序,用户可以在其中将一张卡片添加到一组卡片中,然后将特定卡片的位置与卡片向左或向右切换。我写了一个函数,我相信它会用左侧的卡片切换卡片,但我正在努力调试它,因为所选卡片的索引似乎没有正确传递给子组件。 到目前为止,这是我的代码:

CardList.js 是试图将 moveLeft 方法传递给 cardItem

import React from "react";
import CardItem from "./CardItem";
import CardForm from "./CardForm";
import './Card.css';

class CardList extends React.Component {
  
    state = {
      cards: JSON.parse(localStorage.getItem(`cards`)) || []
      // when the component mounts, read from localStorage and set/initialize the state
    };
  

  componentDidUpdate(prevProps, prevState) { // persist state changes to longer term storage when it's updated
      localStorage.setItem(
        `cards`,
        JSON.stringify(this.state.cards)
      );
  }

  render() {
    const cards = this.getCards();
    const cardNodes = (
      <div style={{ display: 'flex' }}>{cards}</div>
    );

    return (
     <div>
     <CardForm addCard={this.addCard.bind(this)} /> 
     <div className="container">
     <div className="card-collection">
          {cardNodes} 
          </div>
      </div>
      </div>
    );
  }

  addCard(name) {
    const card = {
      name
    };
    this.setState({
      cards: this.state.cards.concat([card])
    }); // new array references help React stay fast, so concat works better than push here.
  }
  
  
  removeCard(index) {
    this.state.cards.splice(index, 1)
    this.setState({
      cards: this.state.cards.filter(i => i !== index)
    })
  }

  moveLeft(index, card) {
    this.setState((prevState, prevProps) => {
        return {cards: prevState.cards.map(( c, i)=> {
            // also handle case when index == 0
            if (i === index) {
                return prevState.cards[index - 1];
            } else if (i === index - 1) {
                return prevState.cards[index];
            }    
        })};
    }); 
 }

  //moveRight(index, card) {
   // ?
 // }

  getCards() {
    return this.state.cards.map((card) => {
      return (
        <CardItem
          card={card}
          index={card.index}
          name={card.name}
          removeCard={this.removeCard.bind(this)}
          moveLeft={this.moveLeft.bind(this)}
        //  moveRight={this.moveRight}
        />
      );
    });
  }
}
export default CardList;

cardItem 正在努力寻找必要卡片的索引,即使我将它作为道具传递。我收到一条错误消息“× TypeError: Cannot read property 'index' of undefined" 源自我的 CardList 组件。

import React from 'react';

import Card from "react-bootstrap/Card";
import Button from "react-bootstrap/Button";

class CardItem extends React.Component {
 render() {
  return (
  <div>
 <Card style={{ width: '15rem'}}>
  <Card.Header as="h5">{this.props.name}</Card.Header>
  <Card.Body>
    <Button variant="primary" onClick={this.handleClick.bind(this)}>Remove</Button>
  </Card.Body>
  <Card.Footer style={{ display: 'flex' }}>
  <i class="arrow left icon" onClick={this.leftClick.bind(this)} style={{ color: 'blue'}}></i>
  {/*<i class="arrow right icon" onClick={rightClick(index, card)} style={{ color: 'blue'}}></i>*/}
  </Card.Footer>
</Card>
 </div>
    )
  }

handleClick(index) { 
  this.props.removeCard(index)
}

leftClick(index, card) {
this.props.moveLeft(index,card)
}

rightClick(index, card) {
  this.props.moveRight(index, card)
}

}
export default CardItem;

我怎样才能最好地将必要的索引作为道具传递下去?谢谢

编辑#1 我在 addCard 方法中犯了一个错误,我从未将索引分配给卡片。我已经解决了这个问题,并在我的地图返回函数中添加了一个关键属性,但现在我收到一条错误消息“× TypeError:无法读取未定义的属性“名称” 请参阅下面更新的 CardList.js:

import React from "react";
import CardItem from "./CardItem";
import CardForm from "./CardForm";
import './Card.css';

class CardList extends React.Component {
  
    state = {
      cards: JSON.parse(localStorage.getItem(`cards`)) || []
      // when the component mounts, read from localStorage and set/initialize the state
    };
  

  componentDidUpdate(prevProps, prevState) { // persist state changes to longer term storage when it's updated
      localStorage.setItem(
        `cards`,
        JSON.stringify(this.state.cards)
      );
  }

  render() {
    const cards = this.getCards();
    const cardNodes = (
      <div style={{ display: 'flex' }}>{cards}</div>
    );

    return (
     <div>
     <CardForm addCard={this.addCard.bind(this)} /> 
     <div className="container">
     <div className="card-collection">
          {cardNodes} 
          </div>
      </div>
      </div>
    );
  }

  addCard(name, index) {
    const card = {
      name,
      index
    };
    this.setState({
      cards: this.state.cards.concat([card])
    }); // new array references help React stay fast, so concat works better than push here.
  }
  
  
  removeCard(index) {
    this.state.cards.splice(index, 1)
    this.setState({
      cards: this.state.cards.filter(i => i !== index)
    })
  }

  moveLeft(index, card) {
    this.setState((prevState, prevProps) => {
        return {cards: prevState.cards.map(( c, i)=> {
            // also handle case when index == 0
            if (i === index) {
                return prevState.cards[index - 1];
            } else if (i === index - 1) {
                return prevState.cards[index];
            }    
        })};
    }); 
 }

  //moveRight(index, card) {
   // ?
 // }

  getCards() {
    return this.state.cards.map((card) => {
      return (
        <CardItem
          card={card}
          key={card.index}
          name={card.name}
          removeCard={this.removeCard.bind(this)}
          moveLeft={this.moveLeft.bind(this)}
        //  moveRight={this.moveRight}
        />
      );
    });
  }
}
export default CardList;

【问题讨论】:

  • 我看不到你在哪里设置你的card.index。在您的addCard 函数中,您只传递了name,并且您没有在返回map 函数时设置key
  • 谢谢,我做了这些更改,但现在我收到了一个不同的错误,如我上面的编辑中所述
  • 您确定您的concat 功能正常工作吗?试试push 看看是否可行。
  • 当我将其更改为推送然后尝试添加新卡时,我得到一个不同的错误,说'TypeError:this.state.cards.map is not a function'
  • 你需要注意几个不同的snafu,比如removeCard(index) { this.state.cards.splice(index, 1),这里你是直接变异状态,这是一个大问题。必须继续前进一段时间,但我猜你正在覆盖你的卡状态,你应该使用调试器或一些 console.logs 来跟踪你的卡状态到底在做什么。

标签: javascript arrays reactjs parent-child react-props


【解决方案1】:

您的addCardremoveCard 函数存在问题。 State updates may be asynchronous 在 React 中,因此您不应在 this.setState 中使用 this.state

例如:addCard 应该如下:

addCard(name, index) {
    let card = {name,index};
    this.setState((prevState, prevProps)=> {
        return prevState.cards.concat(card);
    })
}

removeCard 应同样修改。 splice 也应该被删除,因为 filter 会进行删除。

removeCard(index) {
    this.setState(function(prevState,prevProps) {
        return {cards: prevState.cards.filter(function(card,i) {
            return i != index;
        })};
    });
}

【讨论】:

  • 谢谢,我对 removeCard 编辑感到困惑,我写了这个,但它不起作用:
  • removeCard(index) { this.state.cards(index, 1) this.setState((prevState, prevProps)=&gt; { return prevState.cards.filter(i =&gt; i !== index); }) }
  • 您必须删除包含splice 的整个指令/行。 this.state.cards(index, 1) 应该被删除。
  • 谢谢,我现在有这个,但是当我点击删除按钮时没有任何反应
  • ` removeCard(index) { this.setState((prevState, prevProps)=> { return prevState.cards.filter(i => i !== index); }) }`
猜你喜欢
  • 1970-01-01
  • 2017-12-09
  • 2019-04-14
  • 2020-12-21
  • 1970-01-01
  • 1970-01-01
  • 2019-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多