State

Object inside component we can use to store component state (component personal data, usually dynamic). Not all components need to have state. Components can be stateless and, in fact, are prefered that way.

Lesser the number of component keeping the state, lesser the chance of errors and uncontrolled behavior.

Stateful components cookbook

State object definition (interface) can be set using the second generic term in React.Component

interface AppState{
    counter: number;
}
class App extends React.Component<{},AppState>  {


}

We are required to initialize the state inside the component. We do this in the component constructor or directly on a state member.

class App extends React.Component<{},AppState>  {
    constructor(){
        super();
        // initializing state 
        this.state ={
            counter: 0
        }
    }
}
class App extends React.Component<{},AppState>  {
    // initializing state 
    state = {
        counter: 0
    }
}

State is accessible inside the component via state object.

// inside component
this.state

We can modify the state using setState method (never directly). Calling setState we are triggering component re-render.

class App extends React.Component<{}, AppState>  {
    constructor() {
        super();

        this.state = {
            counter: 0
        }
    }

    clickEvent = () => {
        this.setState({
            counter: this.state.counter + 1 // almost correct, see paragraph below
        })
    }

    render() {
        return (
            <div>
                <button onClick={this.clickEvent} value={this.state.counter} />
            </div>
        );
    }
}

Set state is asynchronous method, when using current state in order to compute a new one, with fast calls your current state reference might not be as current as you expect it to be. Use setState overload that will provide you the correct current state object.

    clickEvent = () => {
        this.setState({
            // will probably not work with fast clickEvent calls, 
            // who knows how old is this.state.counter
            counter: this.state.counter + 1 
        })
        this.setState(state => {
            return {
                counter: state.counter + 1 // correct way to do it
            }
        });
    }

Advanced but crucial

When modifying part of the state - almost always return a new state objects, don't mutate the previous state.

results matching ""

    No results matching ""