2016-01-22 16 views
21

Dla wtyczki używam muszę mieć stan, który wygląda tak:Jak ustawić wartość setState dla macierzy zagnieżdżonej?

getInitialState() { 
    return { 
    invalid: true, 
    access: { 
     access_code: '', 
     zipcode: '', 
     password: '', 
     confirm: '', 
     hospital_id: '', 
    }, 
    } 
}, 

jak bym ustawić stan hospital_id bez ustawiania resztę dostępu?

Wydaje się usunąć wszystko, ale hospital_id:

this.setState({access: {hospital_id: 1}}) 
+0

Mam nadzieję, że React wyjdzie z lepszym sposobem na zrobienie tego, jak na przykład 'updateState()', które zaktualizowałoby tylko przekazane klucze zamiast odwieźć to, co już tam jest. Uważam, że wszystkie te obejścia są niebezpieczne, ponieważ "milkną" w milczeniu, jeśli ktoś zapomni scalić nowy stan z istniejącym stanem. –

Odpowiedz

52

Można użyć Object.assign lub przedmiot Rozłóż propozycję utworzenia kopii obiektów ze zaktualizowanymi właściwościami.

this.setState({ 
    access: { 
    ...this.state.access, 
    hospital_id: 1, 
    }, 
}); 

this.setState({ 
    access: Object.assign({}, this.state.access, { 
    hospital_id: 1, 
    }), 
}); 

Albo najkrótszej wersji i aktualizacji atomowej:

this.setState(({access}) => ({access: { 
    ...access, 
    hospital_id: 1, 
}}); 

I jeszcze jedna opcja jest dodatek aktualizacje:

var update = require('react-addons-update'); 
this.setState({ 
    access: update(this.state.access, { 
    hospital_id: {$set: 1}, 
    }) 
}); 

użyłbym pierwszego.

+3

Biorąc pod uwagę, że React używa najnowszego ES + Babel (w przeważającej części), powinna to być zaakceptowana odpowiedź. Operator rozprzestrzeniania obiektów jest najbardziej zwięzły i łatwy do podrobienia. – ortonomy

+0

Awesome ..... Naprawdę uwielbiam sposób, w jaki działa ES6 –

15

let newAccess = Object.assign({}, this.state.access); 
 
newAccess.hospital_id = 1; 
 
this.setState({access: newAccess});

+9

Nie powinieneś mutować stanu bezpośrednio –

+0

Od kiedy?Reagujący doktorzy nie sugerują takiej reguły. –

+8

[Nie modyfikuj stanu bezpośrednio] (https://facebook.github.io/react/docs/state-and-lifecycle.html#do-not-modify-state-directly) – lolsheeplol

2

Zazwyczaj byś wziąć głęboki kopię obiektu w pytaniu, a potem po prostu zmienić nowe właściwości.

Nie powoduje to jednak usunięcia wszystkiego poza identyfikatorem hospital_id, ale zastępuje go. Ustawienie stanu musi zawierać pełny stan.

Więc albo użyć rozszerzenie sklonować obiekt i zmienić właściwości, lub jeśli nie jest to dużo pracy można zrobić coś takiego:

this.setState({ 
    invalid: state.invalid, 
    access: { 
    access_code: state.access.access_code, 
    zipcode: state.access.zipcode, 
    password: state.access.password, 
    confirm: state.access.confirm, 
    hospital_id: 1, 
    } 
}); 
2

Mój preferowany sposób robi to teraz jest tak proste, jak:

let newAccess = this.state.access; 
newAccess.hospital_id = 1; 
setState({access: newAccess}); 

Nieco prostszy niż obecny odpowiedź zaakceptowana.

EDIT (w oparciu o pytania z @SILENT)

Wygląda to rzeczywiście potencjalnie niebezpieczna metoda. Dalsza lektura tutaj React: A (very brief) talk about immutability.

Wygląda na to lepszy sposób to zrobić byłoby:

let newAccess = Object.assign({}, this.state.access, {hospital_id:1}); 
this.setState({access: newAccess}); 
+1

Czy to nie zmienia stanu? – SILENT

+0

Wygląda na to, że masz rację. Zaktualizowano odpowiedź i zmieniono zaakceptowaną odpowiedź na odpowiedź @FakeRainBrigand –

1

Innym sposobem na to byłoby

const newAccess = {...this.state.access}; 
newAccess.hospital_id = 1; 
setState({access: newAccess}); 

Zastosowanie spread operator tworzy klona this.state.access.

Powiązane problemy