You do not know the props and state

State and Props difference
props is a component of the external interface, state is a component of the internal interface. Between the reference component can reference the other components, the assembly forms a tree structure (tree component), if the lower layer component or method requires the use of data of the upper assembly, the upper assembly can be passed through the lower assembly props attribute, so props It is a component of the external interface. In addition to using the upper assembly component data transfer, but you may also need to maintain their own data management, which is the internal components of the interface state. UI is calculated according to the external interface corresponding to the interface and internal interfaces props state, component.

The main difference:

State variable is a set of states to reflect changes in UI component set;
and Props for the use of its components, is a read-only, in order to modify Props, can only be modified by the parent component of the component.
On assembly shift state of the scene, the parent is through Props component subassembly, the subassembly is transmitted to its desired state.
Props used
when a component is injected into some of the properties (Props) value, the attribute value is derived from its parent element, it is often said, it is a unidirectional flow properties in the React: from parent to child element.

1, props (property) default is "true"
if you did not give prop (properties) by value, he defaults to true. JSX following two expressions are equivalent:

<MyTextBox AutoComplete />
<MyTextBox AutoComplete to true} = {/>
 
In general, we do not recommend the use of this type, because this would ES6 confused with objects in shorthand. In ES6 shorthand {foo} refers {foo: foo} shorthand instead {foo: true}. This behavior only to match the behavior of HTML.
(For example, in HTML, <input type = "radio" value = "1" disabled /> and <input type = "radio" value = "1" disabled = "true" /> is equivalent to .JSX in this behavior it is to match the behavior of HTML.)

2, props extension
if you already have an object type of props, and you want to pass in the JSX, you can use the extended operator ... the whole props incoming object. These two components are equivalent:

function App1() {
return <Greeting firstName="Ben" lastName="Hector" />;
}

App2 function () {
const = {firstName The props: 'Ben', lastName: 'Hector'};
return <the Greeting The props {...} />;
}
 
obviously more convenient following method: because the data is packeted, but also simplifies the writing assignment

State
what a, State yes?
React core idea is component-based, but the most important components of the concept of State (state), State UI is a component of the data model, data is based upon the component rendering.

State (state), and attributes (The props) Similarly, some of the data is a set of components required, but the state is private, may state that a component of the "private property (or local properties)."

How to determine whether the State?
A variable component to be used is not a component State, it may be determined based on the following four:

If this variable is obtained from the parent component by Props? If so, it is not a state.
Whether the variables are held constant throughout the life cycle of components in? If so, it is not a state.
Whether this variable can be calculated by other state (State) or property (Props)? If so, it is not a state.
This variable is used in the render method of assembly? If not, then it is not a state. In this case, more suitable for this variable is defined as a common property of a component, such as the components used in the timer, it should be directly defined as this.timer, rather than this.state.timer.
All state variables are not components used in assembly! When there is a plurality of dependent components together state, the general practice is the shift state, this state of these components into a common parent assembly.

Second, how to properly use State
1, with the modification State setState

Directly modify the state, and will not re-trigger components render ()

// Error
this.state.comment = 'Hello';

right modifications is the use of the setState ()

// correct
this.setState ({Comment: 'the Hello'});

2, is asynchronous update State

After calling setState, setState will want to modify the state into a queue (and therefore state assembly does not change immediately);
after React optimizes real execution timing to optimize performance, the optimization process will more than likely setState state a revised consolidated into a modified state, so state updates may be asynchronous.
So do not rely on the current State, calculate the next State. When the real execution state changes, dependent this.state does not guarantee that the latest State, because React repeatedly State will merge the changes into one, then, this.state will or is this a few times before the State of State changes.
Also note things, the same can not rely on the current Props calculate the next state, because Props are generally obtained from the State of the parent component, still can not determine the value of the updated component status.
To sum up:
this.props and this.state may be asynchronous update, you can not rely on their value calculated under a state (state)

Example:
this counter (counter) will update failed

// Error
this.setState ({
counter: this.state.counter this.props.increment +,
});

To remedy this problem, use the setState () in another form, it takes a function rather than an object. This function takes two parameters:
(1) The first argument: a state before the current date (previous state to the present state sub-assembly)
(2) The second parameter: the current date attribute props

// 正确
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));

// NOTE: This is wrong following
this.setState ((prevState, props) = > {// no use of {} () enclosed, it will resolve to block
counter: prevState.counter props.increment +
}) ;

if you do not know it does not matter, look at the following example:
we now render a button, want every click, counter to +3
look at the code below:

class App extends React.Component {
state = {
counter: 0,
}
handleClick = () => {
const { counter } = this.state;
//或者 const counter = this.state.counter;
this.setState({ counter: counter + 1 });
this.setState({ counter: counter + 1 });
this.setState({ counter: counter + 1 });
}
render() {
return (
<div>
counter is: {this.state.counter}
<button onClick={this.handleClick} >点我</button>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));

输出:

Per click, plus +1, +3 not


The reason +1, +3 not, because the update state may be asynchronous, React will pass more than more setState Object of "batch" up merged into one. Combined into one equivalent to a plurality of incoming setState Object is shallow merge, like this:

Update = {const
counter: counter + 1,
counter: counter + 1,
counter: counter + 1
// Because of the above three sentences are the same, so when the sentence will be executed
}

we can do will succeed: see below

{React.Component the extends the App class
State = {
counter: 0,
}
the handleClick = () => {
this.setState (PREV => ({counter: prev.counter +. 1}));
this.setState (PREV => ( counter {:} prev.counter +. 1));
this.setState (PREV => ({counter: prev.counter +. 1}));
// this is wrong this.setState (prev => {counter: prev. } +. 1 counter);
// this is wrong this.setState (PREV => {counter: ++ prev.counter});
// this is wrong this.setState (prev => {counter: prev.counter ++} );
}
the render () {
return (
<div>
counter IS: {} this.state.counter
<Button this.handleClick the onClick = {}> I site </ Button>
</ div>
)
}
}
ReactDOM.render (<App />, document.getElementById ( 'root'));

achieved because: a plurality of incoming setState plurality Object will be shallow Merge, a plurality of incoming and a plurality of function will setState the "queue" up, queue in the reception function to State (the above is prev) before the function is a manipulated state.

3, State update will be merged
official document do not understand it does not matter, for example direct you understand.

Such as the status of a component:

= {this.state
title: 'React',
Content: '! IS AN Wonderful React the JS Library'
}

when only need to modify the state of title, the title simply apply the modified pass setState:

this.setState ({title: 'Reactjs'});
. 1
React title will incorporate the new component to the original state, while retaining the original state of content, State combined as follows:

{
Title: 'Reactjs',
Content: '! IS AN Wonderful React the JS Library'
}

. 4, the update order in the setState

// history array
this.setState ({
History: history.concat ([. 1]), // (. 1)
Current: history.length, // (2)
nextPlayer:! nextPlayer, // (. 3)
});

when executed setState: first update history, and then use the update history of the changed calculation of the value of current, and finally update nextPlayer

Third, according to the type of State updated
when the state changes, how to create a new state? Depending on the type of state, it can be divided into three cases:

1, the type is immutable state (numbers, strings, Boolean values, null, undefined)

This is the simplest case directly to the state to be modified to assign a new value

// original State
this.state = {
COUNT: 0,
title: 'React',
Success: to false
}
// change State
this.setState ({
COUNT:. 1,
title: 'BTY',
Success: to true
})

2, state the type is an array of
arrays is a reference, when compared React diff algorithm is executed two references, not a reference object. So directly modify the original object, a reference value does not change, then, React will not re-render. Thus, when an array or modify an object's state, to return a new array or an object.
(1) increases
if a state array type books, a book when the increase in books (chinese), concat method using an array of arrays or extended syntax for ES6

@ Method a: the first state is assigned to another variable, and then create a new array concat using
the let Books = this.state.books;
this.setState ({
Books: books.concat ([ 'chinese'])
})

// two: preState, concat create a new array
this.setState (preState => ({
Books: preState.books.concat ([ 'chinese'])
}))

@ Method three: Spread syntax for ES6
this.setState (preState => ({
books: [... preState.books, 'chinese']
}))

(2) taken
when part of the element taken from the books as a new state, method using an array of slice:

@ Method a: the first state is assigned to another variable, and then create a new array slice using
the let Books = this.state.books;
this.setState ({
Books: books.slice (l, 3)
})
//
// Option two: preState, slice create a new array
this.setState (preState => ({
books: preState.books.slice (l, 3)
}))

(. 3) condition filtration
when the filter element portion from the books as a new state, using an array of filter method:

@ Method a: the first state assigned to the additional variables, then create a new filter array
var = this.state.books Books;
this.setState ({
Books: books.filter (Item => {
return Item = 'React! ';
})
})

// two: preState, filter create a new array
this.setState (preState => ({
: Books preState.books.filter (Item => {
; return Item = 'React'!
})
)})

Note: Do not use the push, pop, shift, unshift, splice or the like to modify the state of the array type, since these methods are based on the modification of the original array, and concat, slice, filter returns a new array.

3, the state of an ordinary type of an object (which is a string, array)
an object is a reference, when the comparison executed React diff algorithm is two references, rather than a reference object. So directly modify the original object, a reference value does not change, then, React will not re-render. Thus, when an array or modify an object's state, to return a new object.
Use ES6 method of Object.assgin

@ Method a: the first state assigned to the additional variables, then create new objects Object.assign
var owner = this.state.owner;
this.setState ({
owner: Object.assign ({}, owner, {name: 'Jason'})
})

// two: preState, Object.assign create a new object
this.setState (preState => ({
owner: Object.assign ({}, preState.owner, {name: 'Jason'})
}))

using object extension syntax (object spread properties)

@ Method a: the first state is assigned to another variable, and then use the object extended syntax to create a new object
var owner = this.state.owner;
this.setState ({
owner: {... owner, name: 'Jason'}
})

// two: preState, object extension syntax to create a new object
this.setState (preState => ({
owner: {... preState.owner, name: 'Jason'}
}))

 

To sum up:
to create a new state of the object key is to avoid the use of directly modifying the original object's methods, but the use to return a new object.

Four, State flows down
we said props is a component of the external interface, state is a component of the internal interface.
A component can choose to State (state) passed downwardly, as The props (property) of its subcomponents:

<This.state.title the MyComponent title = {} />
. 1
This is commonly referred to as a "top-down", or "one-way" flow of data. Any state (state) always by a specific component of all and any data or derived from the UI state (state) can only affect the component in the tree "below".

If the component tree imagined as props (property) waterfall, state all the components of the (state) just as an additional source of water into the mainstream, and only with the mainstream flow direction downwards.

Guess you like

Origin www.cnblogs.com/husfBK/p/11540379.html