J'ai un modèle de modèle d'objet comme ci-dessous
// To update the state model with changed values
setData = (key, val) => {
this.setState(state => ({
data: {
...state.data,
obj: { [key]: val },
//Don't know how to map to state properly!
}
}));
};
// Handle input change
handleChange = key => e => {
this.setData(key, e.target.value);
};
Mon objectif est de:
Je n'ai pas utilisé de tableau, car il doit ressembler au modèle d'objet ci-dessus lors de sa publication.
Pour le moment, voici comment j'essaye de faire ceci:
//To render
Object.entries(this.state.data).map((x,index) =>
<p>x.key</p> //Trying to reach 'audi' with x.key
// Render each KPV in object
{x.key}: <input key={index} onChange={this.handleChange} value={x.value}/>
)
Ensuite, pour mettre à jour les valeurs correspondantes dans le même modèle d'état:
this.state = {
data: {
audi: {
engine: '2.5',
gearbox: 'auto',
fuel: 'petrol'
},
bmw: {
engine: '3.0',
gearbox: 'auto',
fuel: 'petrol'
},
merc: {
engine: '6.3',
gearbox: 'manual',
fuel: 'petrol'
}
}
}
S'il vous plaît, quelqu'un pourrait-il me conseiller sur cette approche, merci beaucoup :)
3 Réponses :
Vous ne passez pas la clé et l'objet d'événement à partir du rappel d'entrée en premier lieu, votre code devrait être comme,
La logique d'affichage me semble fausse,
handleChange = (key, e) => {
this.setData(key, e.target.value);
};
et le rappel handleChange devrait ressembler à, ne les curry pas.
Object.entries(this.state.data).map((x, index) =>
/*
here x is an array and it looks like
["audi", {engine: '2.5', gearbox: 'auto', fuel: 'petrol}
*/
// You need to access the data in the second index
// if you want to print each value of the object
<p>x[1].engine</p>
<p>x[1].gearbox</p>
<p>x[1].fuel</p>
// Render each KPV in object
{x[0]}: <input key={index} onChange={(e) => this.handleChange(x[0], e)} value={x[1].engine}/>
)
Et je suggérerais d'utiliser un utilitaire tel que castArray de lodash, https://lodash.com/docs/4.17.15#castArray pour convertir l'objet en tableau afin que vous puissiez facilement travailler avec lui.
Vous devez d'abord obtenir le bon rendu, ce qui signifie boucler toutes les clés (constructeurs automobiles), puis toutes les paires propriété / valeur. Vous pouvez utiliser des tableaux de déstructuration pour rendre cela plus facile
// To update the state model with changed values
setData = (maker, key, val) => {
this.setState((state) => ({
data: {
...state.data,
[maker]: {
...state.data[maker],
[key]: val
}
//Don't know how to map to state properly! Now you do!
}
}));
};
// Handle input change
handleChange = (maker, key) => (e) => {
this.setData(maker, key, e.target.value);
};
Rendu Heres:
render() {
return Object.entries(this.state.data).map(([maker, props]) => {
return (
<div>
<h2>{maker}</h2>
{Object.entries(props).map(([key, value], index) => {
return (
<div>
{key}:{" "}
<input
key={index}
onChange={this.handleChange(maker, key)}
defaultValue={value}
/>
</div>
);
})}
</div>
);
});
}
Vous noterez que j'ai changé votre méthode handleChange pour transmettre le constructeur automobile et la propriété en cours de modification - cela peut être passé à setData :
Object.entries(someObject).map( ([key,value]) => .... )
Exemple de travail en direct: https://codesandbox.io/s/react-playground-forked-dw9sg
Merci @Jamiec cela m'a aidé beaucoup
<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>
body { font-family: monospace; }
span { display: block; font-weight: bold; }
input { width: 50px; }class App extends React.Component {
constructor(props) {
super(props)
this.state = {
data: {
audi: { model: "A7", transmission: "AT" },
merc: { model: "GLA", transmission: "MT" },
bmw: { model: "M3", transmission: "AT" },
},
}
}
update(make, detail, value) {
let data = this.state.data
data[make][detail] = value
console.log(`Updating ${make} ${detail} with ${value}`)
this.setState({ data: data })
}
handleChange(make, detail) {
return e => { this.update(make, detail, e.target.value) }
}
renderDetails(details) {
return details.map(d => (<div><span>{d.key}:</span> <input value={d.model} onChange={this.handleChange(d.key, "model")} /> <input value={d.transmission} onChange={this.handleChange(d.key, "transmission")} /></div>))
}
render() {
const details = Object.entries(this.state.data).map(d => ({ key: d[0], ...d[1] }))
return <div>{this.renderDetails(details)}</div>
}
}
ReactDOM.render((<App />), document.getElementById("app"))
À quel problème êtes-vous confronté en fait?
Comment l'attendez-vous exactement, partagez un échantillon si possible?