freeCodeCamp/guide/english/react/react-props-state/index.md

5.3 KiB
Raw Blame History

title
React Props and State

Props & State

There are two types of data that control a component: props and state. Props are set by the parent and they are fixed throughout the lifetime of a component. For data that is going to change, we have to use state.

Props

Most components can be customized with different parameters when they are created. These creation parameters are called props.

Your own components can also use props. This lets you make a single component that is used in many different places in your app, with slightly different properties in each place. Refer to this.props in your render function:

class Welcome extends React.Component {
  render() {
    return <h1>Hello {this.props.name}</h1>;
  }
}

const element = <Welcome name="neel" />;

The line <Welcome name="neel" /> creates a property name with value "neel".

the property is passed to the component, similar to how an argument is passed to a function. In fact, we could even rewrite the component to be simpler:

function Welcome(props) {
  return <h1>Hello {props.name}</h1>;
}

We can make the name property optional by adding defaultProps to the Welcome class:

class Welcome extends React.Component {
  render() {
    return <h1>Hello {this.props.name}</h1>;
  }
}

Welcome.defaultProps = {
  name: "world",
};

If Welcome is called without a name it will simply render <h1> Hello world</h1>.

So props can come from the parent, or can be set by the component itself.

You used to be able to change props with setProps and replaceProps but these have been deprecated. During a components life cycle props should not change (consider them immutable).

Since props are passed in, and they cannot change, you can think of any React component that only uses props (and not state) as “pure,” that is, it will always render the same output given the same input. This makes them really easy to test.

State

Like props, state holds information about the component. However, the kind of information and how it is handled is different.

By default, a component has no state. The Welcome component from above is stateless:

function Welcome(props) {
  return <h1>Hello {props.name}</h1>;
}

When a component needs to keep track of information between renderings the component itself can create, update, and use state.

Well be working with a fairly simple component to see state working in action. Weve got a button that keeps track of how many times youve clicked it.

heres the code:

class Button extends React.Component {
  constructor() {
    super();
    this.state = {
      count: 0,
    };
  }

  updateCount() {
    this.setState((prevState, props) => {
      return { count: prevState.count + 1 }
    });
  }

  render() {
    return (<button
              onClick={() => this.updateCount()}
            >
              Clicked {this.state.count} times
            </button>);
  }
}

state is created in the component

Lets look at the constructor method:

constructor() {
  super();
  this.state = {
    count: 0,
  };
}

This is where state gets its initial data. The inital data can be hard coded (as above), but it can also come from props.

state is changeable

Heres updateCount method:

updateCount() {
  this.setState((prevState, props) => {
    return { count: prevState.count + 1 }
  });
}

We change the state to keep track of the total number of clicks. The important bit is setState. First off, notice that setState takes a function, thats becuase setState can run asynchronously. It needs to take a callback function rather than updating the state directly. You can see we have access to prevState within the callback, this will contain the previous state, even if the state has already been updated somewhere else.

React goes one step better, setState updates the state object and re-renders the component automagically.

state warnings

It is tempting to write this.state.count = this.state.count + 1.

Don't do this React cannot listen to the state getting updated in this way, so your component will not re-render. Always use setState.

It might also be tempting to write something like this:

// DO NOT USE
this.setState({
  count: this.state.count + 1
});

Although this might look reasonable, doesnt throw errors, and you might find examples that use this syntax online, it is wrong. This does not take into account the asychronous nature that setState can use and might cause errors with out of sync state data.

Program Continue !!!

And finally, render

render() {
  return (<button
            onClick={() => this.updateCount()}
          >
            Clicked {this.state.count} times
          </button>);
}

onClick={() => this.updateCount()} means that when the button is clicked the updateCount method will be called. We need to use ES6s arrow function so updateCount will have access to this instances state.

The text rendered in the button is Clicked {this.state.count} times, which will use whatever this.state.count is at the time of rendering.

More Info about: React props and state