The introduction
React this.setstate ({XXX :”}) differs from this.state. XXX =”.
Answer: there is a difference.
This. state is usually used to initialize state, and this.setstate is used to modify state values. If you use this.state after initializing state, the previous state will be overwritten. If you use this.setState, only the corresponding state value will be replaced.
A, enclosing setState ({})
- This.setstate ({}) triggers the Render method to rerender the interface. This.state. XXX = “does not reload the UI.
- This.setstate ({}) is asynchronous.
Second, the enclosing state. XXX = ‘ ‘
In what scenario would this.state. XXX be used?
When I wrote two buttons, clicked the button to update and change the value of state, and then requested the data of state as a parameter to automatically refresh the UI of the list, something went wrong.
Example:
constructor(){
this.state={
couponStatus : 0,}}render() {
<SegmentedBar
justifyItem='fixed'
indicatorType='customWidth'
indicatorLineColor='#f5e220'
indicatorWidth={90}
animated={false}
onChange={(index)= >{ this.setState( { couponStatus:index; }}}} >}Copy the code
The above code does not achieve the desired effect, why? Because setState is asynchronous and has some delay, sometimes the state has not changed after the list loading data has been completed, which leads to the direct result of data corruption. So we changed the code a little bit.
this.state.couponStatus = index; / / don't forget to manually refresh the list UI enclosing refs. CouponListView. Refresh ();Copy the code
And that’s the perfect solution.
3. Immutability
As you can see from the example above, this. State can be treated as a read-only property, similar to this.props. The setState method should always be used to update the state of the component’S UI, rather than directly modifying this.state. React updates the interface when this.setstate () is called. This is the most common case, but there are exceptions, such as making the life cycle function shouldComponentUpdate() return false to avoid interface updates.
By immutability, the title refers to replacing an object without modifying it.
Suppose we now have a stateful component that displays tickets for an airline:
import React,{Component} from 'react';
class Test extends Component{
constructor(){
super(... arguments)this.state={
passengers: ['Simmon'.'Taylor']}}render(){...}
}
Copy the code
Now you need to add a new passenger to the Passengers array. If you’re not careful, you can inadvertently modify the component’s state object directly. Such as:
let newPassengers = this.state.passengers;
// In js, objects and arrays are passed by reference, which means that this line of code does not create a copy of the array,
// Just create a new reference that points to the array in the state of the current component.
// So using push in the next code is directly modifying state.
newPassengers.push('Jay');
this.setState({
passengers: newPassengers
})
Copy the code
To create an actual copy of an array in JS, you need to use non-invasive array methods, that is, methods that return a new array rather than modifying the original array directly. Map, filter, concat, and slice are all non-invasive array methods of this form.
In JS, there are other ways to create new objects based on the original Object, such as using object.assign. Object.assign has compatibility issues, but this can be addressed with Babel and is not detailed here.
Use Array’s concat method to add functionality:
let newPassengers = this.state.passengers.concat('Jay');
this.setState({
passengers: newPassengers
})
Copy the code
4. Nested objects (shallow copy and deep copy)
1. Concepts of deep copy and shallow copy
How to distinguish deep copy from shallow copy?
In simple terms, suppose B copies A. When YOU modify B, see if A changes. If A also changes, it is A shallow copy. If A doesn’t change, it’s A deep copy.
1. Shallow copy: Assign a reference to the original object or array directly to the new object. The new array is just a reference to the original object
2. Deep copy: Create a new object and array, copy the “values” (all the elements of the array) of the original object, “values” instead of “references”.
Why use deep copy?
We want to change the new array without changing the original array.
How deep copy is required?
When using deep copy, it is important to know to what extent we require deep copy: do we “deep” only the first level of object properties or array elements, or do we recursively copy all levels of object properties and array elements?
2. Nested objects
In most cases, the non-invasive approach to arrays and object. assign will do what we want, but if state contains nested objects or arrays, things get tricky. Because of the nature of Js, both objects and arrays are passed by reference, and the non-invasive array and object. assign methods do not make deep copies. In practice, this means that the nested objects and arrays contained in the new Object you create with the array non-invasive method and object. assign still refer to the nested objects and arrays in the original Object.
React invariant assistant — update
The update function applies to ordinary JS objects and arrays to wrap them as immutable objects: the function doesn’t actually modify these objects, but always returns a new mutable object.
React-addons-update-npm
Install: NPM I react-addons-update
Import update from ‘react-addons-update’
The update function takes two arguments. The first argument is the object and array that you want to update. The second argument is an object that describes where and what changes you want to make.
For example:
let student = {name:'Jonn'.grades: ['A'.'B'.'C']}
// To create a copy of this object after the modified Grades, the use of the update function is as follows:
let newStudent = update(student,{grades: {$push: ['A']}})
Copy the code
The {grades:{$push:[‘A’]}} object from left to right indicates that the update function should:
- Locate the Grades property (” where “the changes should be applied)
- Add a new value to the array (” where “modification should be applied)
If you want to modify the entire array completely, you can replace set with set instead of push:
let newStudent = update(student,{grades: {$set: ['A'.'A'.'B']}})
Copy the code
There is no limit to how many layers you can nest in an object. Array indexes can be used when appropriate:
a={
code:[
{company:'GL'.No:'9'},
{company:'TM'.No:'3'}
]
}
b=update(a,{
code: {0: {$set: {company:'AZ'.No:'5'}}}})Copy the code
Update command
The command | describe |
---|---|
$push | Similar to the Array push function, it adds one or more elements to the end of an Array. |
$unshift | Similar to Array’s unshift function, it adds one or more elements to the head of an Array. |
$splice | Similar to the Array splice function, it modifies the contents of an Array by removing elements from and/or adding elements to the Array. The main syntactic difference from array.splice is that you need to supply an Array of elements as arguments, each of which contains the parameters to splice the Array. |
$set | Replace the entire target completely. |
$merge | Merges the key of the given object into the target object. |
$apply | You pass the current value to a function, modify the passed value in the function, and then use the return value of the function as the result. |
Code examples:
let a = [1.2.3]
let b = update(a,{$push: [4]})
/ / = > [1, 2, 3, 4]
let a = [1.2.3]
let b = update(a,{$unshift: [0]})
/ / = >,1,2,3 [0]
let a = [1.2.'a']
let b = update(a,{$splice: [[2.1.3.4]]})
/ / = > [1, 2, 3, 4]
let ob = {a:5.b:3}
let newOb = update(ob,{$merge: {b:6.c:7}})
// => {a:5,b:6,c:7}
let ob = {a:5.b:3}
let newOb = update(ob,{b: {$apply:(value) = >value*2}});
// => {a:5,b:6}
Copy the code
Reference links:
1. React Native this.setstate ({XXX: “}) is different from this.state. XXX = “? React Development Practice — Cssio de Sousa Antonio. Translated by Du Wei, Chai Xiaowei and Tu Shuguang