2
votes

ReactJS sélectionne un élément uniquement à partir d'une carte

Je crée une application todo pour m'entraîner à React. J'ai frappé un bloqueur et maintenant j'essaie de comprendre comment modifier de manière unique une carte.

Actuellement, lorsque je clique sur modifier, toutes mes cartes sont définies sur isEditing == true . J'ai essayé d'ajouter une clé et un index, mais ne semble pas identifier de manière unique la carte sélectionnée.

Comme vu dans mon gif:

entrez la description de l'image ici

De toute évidence, le résultat attendu est qu'il ne doit définir que isEditing == true à la carte sélectionnée.

Voir le code ci-dessous.

Pour plus de contexte: il y a avec état composant qui passe les accessoires à ce composant, j'utilise react-bootstrap (d'où Panel , Button ), et j'ai supprimé du code pour brièveté ( construction et autres).

    edit() {
        this.setState({
            isEditing: true
        })
    }

    renderEditDoneButtons() {
        return (
            <div>
                <Button onClick={this.edit}>edit</Button>
            </div>
        )
    }

    renderNote(note) {
        return (
            <p> {note} </p>
        )
    }

    renderCard(note, i) {
        return (
            <Panel key={i}
                   index={i}>
                {
                    this.state.isEditing ? 
                    this.renderForm() : 
                    this.renderNote(note.note)
                }
            </Panel>
        )
    }

    render() {
        return (
            <div>
                {this.props.notes.map(this.renderCard)}
            </div>
        )
    }  


3 commentaires

Comment le bouton renderEditDoneButtons () est-il lié avec le même identifiant à la carte? Si le bouton a le même identifiant que la carte, vous pouvez créer un tableau qui a un état d'édition individuel pour chaque carte. Ou vous pouvez avoir un varaible qui stocke l'identifiant de la carte en cours de modification et vous pouvez afficher cette carte en conséquence


Voir: stackoverflow.com/questions/44409731/...


Voulez-vous pouvoir en modifier un seul à la fois? Ou souhaitez-vous autoriser l'utilisateur à activer / désactiver la modification?


3 Réponses :


0
votes

Vous devez avoir la variable d'état isEditing pour chaque carte particulière. S'il y a 3 cartes, vous devez avoir 3 variables.

Édition 1: - L'exemple est déjà partagé par Kody R.

Une chose que j'ai remarquée est qu'au lieu de coder en dur la taille du tableau à 3, nous pourrions attribuer la taille du tableau en fonction du nombre de notes reçues dans les accessoires.

this.state = {
    editingPanels: Array(this.props.notes.length).fill(false)
  }

À p >

this.state = {
    editingPanels: Array(3).fill(false)
  }

J'espère que cela vous aidera,

Bravo !!


0 commentaires

4
votes

Tous les trois changent en fonction de votre état unique isEditing , c'est pourquoi vous voyez tous les trois s'afficher lorsque vous cliquez sur l'un des boutons "Modifier". Au lieu d'une seule clé isEditing dans l'état, utilisez un tableau pour conserver les trois états comme suit:

constructor(props) {

  super(props);

  // Sets a true/false editing state for all three panels
  this.state = {
    editingPanels: Array(3).fill(false)
  }
}

edit(i) {

    // Switches editing state to false/true for given i
    const editingPanels = this.state.editingPanels.slice();
    editingPanels[i] = !editingPanels[i];

    this.setState({
        editingPanels: editingPanels
    })
}

renderEditDoneButtons(i) {
    return (
        <div>
            <Button onClick={()=>this.state.edit(i)}>edit</Button>
        </div>
    )
}

renderNote(note) {
    return (
        <p> {note} </p>
    )
}

renderCard(note, i) {
    return (
        <Panel key={i}
               index={i}>
            {
                this.state.editingPanels[i] ? 
                this.renderForm() : 
                this.renderNote(note.note)
            }
        </Panel>
    )
}

render() {
    return (
        <div>
            {this.props.notes.map(this.renderCard)}
        </div>
    )
} 


2 commentaires

const editPanels = this.state.editingPanels.slice (); pourrait-il avoir été refactorisé en const editorPanels = this.state.editingPanels


@ e_mam106 correct - Facebook recommande d'utiliser slice si vous voulez suivre l'historique des entrées de l'utilisateur, donc je le fais par habitude :)



1
votes

Vous pouvez utiliser un composant séparé pour chaque élément de la liste de tâches et l'utiliser dans la méthode map.L'exemple suivant donne une idée sur la façon de l'implémenter.J'utilise un autre exemple car vous n'avez pas fourni le code complet.

class EditText extends React.Component {
  constructor(props) {
    super(props)
    this.state = {value:props.data,newValue:'hi'}
    this.editValue = this.editValue.bind(this)
  }
  editValue() {
    this.setState({value:this.state.newValue})
  }
  render() {
    return(
      <div>
      {this.state.value}
      <button onClick={this.editValue}>Change text to Hi</button>
      </div>
    )
  }
}
class App extends React.Component {
  constructor() {
    super()
    this.state = {tempDate : ['hello','how']}
  }
  render() {
    return (
      <div className="App">
      {this.state.tempDate.map(data=>(<EditText data={data}/>))}
      </div>
    );
  }
}


0 commentaires