reactjs - Er det greit å endre state direkte før man kaller setState()?
Jeg bruker en lettvekts ORM for å koble React-appen min til en ekstern tjeneste... Dette pakken returnerer objekter av modellen din og lar deg utføre operasjoner direkte på dem. Selv om dette er veldig flott, sliter jeg med å finne ut hvordan jeg kan inkludere disse objektene i state og fortsatt følge prinsippet om å "aldri endre state direkte" i React.
Hvis jeg hadde en komponent som oppdaterte kontonavnet, ville det være akseptabelt å gjøre noe sånt som dette?
interface IAppState {
account: Account
}
class App extends React.Component<{}, IAppState> {
constructor(props) {
super(props);
this.state = {
account: new Account()
}
}
//set the new name and update the external service
public updateAccount = (newName: string)=>{
account.name = newName; //REDFLAG!!!
acc.update().then(()=>{
this.setState({ account: this.state.account })
})
}
//retrieve our account object from external service
public componentDidMount() {
const qParams = queryString.parse(window.location.search);
Account.get(qParams.externalId).then((acc)=>{
this.setState({account: acc})
})
}
render() {
return <NameEditor handleClick={this.updateAccount} account={a} />
}
}
Jeg antar jeg kunne unngå å endre tilstanden ved å opprette et tomt ORM-objekt, kopiere egenskapene over, sende oppdateringen og deretter sette tilstanden, men dette virker som en stor plage.. Spesielt siden disse ORM-objektene kan inneholde underordnede ORM-objekter som jeg også ønsker å kunne endre.
Er måten jeg muterer tilstanden på ovenfor «farlig» eller «dårlig praksis»???
Oppdater
Gjorde litt lesing, og det virker definitivt som om dette sannsynligvis er dårlig fremgangsmåte og kan kanskje håndteres elegant ved å bruke react/addons... Men hva om ORM-kallet har en bivirkning på objektet? For eksempel setter det å kalle insert objektets eksterne ID-felt.
Svar #1
public updateAccount = (newName: string)=>{
//account.name = newName; //REDFLAG!!!
// You can use the below code to update name after it is updated
// on server.
// This will work because the object being passed here
// will be merged with Component state.
acc.update().then(()=>{
this.setState({account: {name : newName}})
})
}
Direkte endring av tilstanden anbefales ikke, da React ikke vil bli kjent med endringen og det vil ikke føre til en gjengivelse på nytt.
All diffing skjer på Virtual DOM, og React oppdaterer kun de endrede attributtene til Browser DOM. Du kan lese mer om Reacts diffing-algoritme her.
Svar #2
React anbefaler å bruke uforanderlige objekter for å sette tilstand. Du kan enten bruke Object.assign eller immutable.js til dette formålet, noe som vil gjøre livet vårt enklere. Hvis du endrer ditt tilstandsobjekt, vil det påvirke ytelsen til din React-komponent.
Du kan referere til lenken nedenfor for mer informasjon.
https://facebook.github.io/react/docs/optimizing-performance.html#examples
