Jeg prøver at ændre state
i en klassekomponent ved at bruge setState
.
Mere specifikt har jeg en tabel, og jeg vil redigere/opdatere et af dens elementer. I dette tilfælde videregiver jeg indeces til handleTableFieldOnChange
funktion for værdiens position i arrayet.
Da jeg ved, at jeg ikke bør mutere tilstanden, brugte jeg et eksternt bibliotek til at kopiere tabellernes array/liste i dybden.
Den dybe kopi og den nye værditildeling virker. Den dybe kopi fungerede også med JSON.parse(JSON.stringify(this.state.tables));
alternativ.
Problem: Af en eller anden grund er this.setState(...)
ændrer ikke tabellernes værdi.
Jeg kender setState
er asynkron, det er derfor, jeg brugte tilbagekaldet og i det, console.log(...)
for at kontrollere den opdaterede værdi.
console.log(...)
udsender stadig den gamle værdi.
private handleTableFieldOnChange(val: boolean | string | number | [number, string], tblRowIndex: number, tblIndex: number, tblColINdex: number) { const cloneDeep = require('lodash.clonedeep'); const newTables = cloneDeep(this.state.tables); if (newTables && newTables[tblIndex] && newTables[tblIndex].items ) { newTables[tblIndex].items![tblRowIndex][tblColINdex].value = val; } this.setState( {tables: newTables}, () => { console.log(this.state.tables) }) } state: State = { tables: [], report: this.props.report, }; constructor(props: DetailProp, state: State) { super(props, state); this.initFieldsAndTabels(); } private initFieldsAndTabels() { if (this.state.report && this.state.report.extraction_items) { this.state.tables = []; this.state.report.extraction_items.forEach((extractionItems) => { this.state.tables.push(extractionItems); }); } }
Svar
Koden i handleTableFieldOnChange
ser fint ud for mig.
Dog i initFieldsAndTabels
du anvender push
på tilstand direkte i stedet for at ringe til setState
hvilket sandsynligvis kan forårsage problemerne:
this.state.report.extraction_items.forEach((extractionItems) => { this.state.tables.push(extractionItems); //#HERE });
Også som React.Component-dokumenter siger, bør du ikke kalde setState
i constructor
(du ringer til initFieldsAndTabels
i constructor
. I stedet kan du bruge componentDidMount
.
P.S. Hvis du vil tilføje disse ekstraktionselementer i konstruktøren, har du brug for noget som dette:
constructor(props) { super(props); // method should return a new array/object, but not modify state const tables = this.initFieldsAndTabels(); this.state = { tables, } }