reactjs - Är det okej att ändra state direkt innan man kallar setState()?
Jag använder en lättviktig ORM för att koppla min React-app med en extern tjänst... Detta paket returnerar objekt av din modell och låter dig utföra operationer direkt mot dem. Även om detta är riktigt fantastiskt, har jag svårt att lista ut hur jag kan inkludera dessa objekt i state och fortfarande följa ”ändra aldrig state direkt”-principen i React.
Om jag hade en komponent som uppdaterade kontonamnet, skulle det vara acceptabelt att göra något sådant här?
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} />
}
}
Jag antar att jag skulle kunna undvika att mutera tillståndet genom att initiera ett tomt ORM-objekt, kopiera egenskaperna över, skicka uppdateringen och sedan sätta tillståndet, men detta verkar vara en stor besvärlighet.. Särskilt eftersom dessa ORM-objekt kan innehålla barn-ORM-objekt som jag också skulle vilja kunna modifiera.
Är sättet jag ändrar state ovanför "farligt" eller "dålig form"???
Uppdatera
Gjorde lite läsning och det verkar definitivt som om detta förmodligen är dålig praxis och kan hanteras elegant med react/addons... Men vad om ORM-anropet har en bieffekt på objektet? Till exempel, att anropa insert sätter objektets externa id-fält.
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}})
})
}
Att direkt ändra tillstånd rekommenderas inte eftersom React inte kommer att känna till förändringen och det kommer inte att orsaka en omrendering.
All diffing sker på Virtual DOM och React uppdaterar endast ändringsattributen till Browser DOM. Du kan läsa mer om Reacts diffningsalgoritm här.
Svar #2
React rekommenderar att använda oföränderliga objekt för att sätta state. Du kan antingen använda Object.assign eller immutable.js för detta ändamål, vilket kommer att göra vårt liv enklare. Om du ändrar ditt state-objekt kommer det att påverka prestandan hos din React-komponent.
Du kan hänvisa till länken nedan för mer information.
https://facebook.github.io/react/docs/optimizing-performance.html#examples
