Author avatar

Gaurav Singhal

How to Send State of Current Component as a Parameter to Another External Method Using React

Gaurav Singhal

  • Sep 15, 2020
  • 6 Min read
  • 92,947 Views
  • Sep 15, 2020
  • 6 Min read
  • 92,947 Views
Web Development
Front End Web Development
Client-side Framework
React

Introduction

Communicating data between React components is crucial as it allows you to create more dynamic web applications. But since React has only one-way data flow, it can get tricky to communicate or send data to other components.

To update the state in a parent component, you have to pass the data into the callback prop. Instead of giving the data or state into the callback prop, you can send it directly to an external method to complete a specific task. In this guide, you'll learn how to submit a component's state to an external method.

State in React

In React, the state of the component is an object that contains some data. The state may change over the lifecycle of the component. Earlier, states were only used in class-based components, but now because of hooks, you can use the useState hook to leverage state in a function-based component.

Passing State to a Component

Before diving into how to send state to an external method, take a look at how to pass it to a component.

To pass the state into another component, you can pass it as a prop.

1class ParentComponent extends Component {
2    state = {
3        // ..
4    }
5    render() {
6        return <ExampleComponent data={this.state}>
7    }
8}
jsx

Then, inside <ExampleComponent />, you can access the data as this.props.data.

Passing State to an External Method

Sending state to an external method is similar to passing state to a child component. Passing this.state into the external method's parameter will do the trick.

Let's take an example of a login form from the React Bootstrap documentation. It will have the email and password in its state.

1class LoginForm extends Component {
2  state = {
3    email: "",
4    password: ""
5  };
6
7  handleChange = e => this.setState({ [e.target.name]: e.target.value });
8
9  render() {
10    return (
11      <Form>
12        <h2>Login</h2>
13        <hr />
14        <Form.Group controlId="formBasicEmail">
15          <Form.Label>Email address</Form.Label>
16          <Form.Control
17            type="email"
18            placeholder="Enter email"
19            onChange={this.handleChange}
20          />
21          <Form.Text className="text-muted">
22            We'll never share your email with anyone else.
23          </Form.Text>
24        </Form.Group>
25
26        <Form.Group controlId="formBasicPassword">
27          <Form.Label>Password</Form.Label>
28          <Form.Control
29            type="password"
30            placeholder="Password"
31            onChange={this.handleChange}
32          />
33        </Form.Group>
34        <Form.Group controlId="formBasicCheckbox">
35          <Form.Check type="checkbox" label="Check me out" />
36        </Form.Group>
37        <Button variant="primary" type="button">
38          Submit
39        </Button>
40      </Form>
41    );
42  }
43}
jsx

Pass the state of the <LoginForm /> component to a loginUser() external method, which will handle the network request to check whether the email and password are correct.

The loginUser() method is shown below.

1const loginUser = async values => {
2  const res = await fetch({ url: SERVER_URL, method: "POST", body: values });
3  const data = await res.json();
4  return data;
5};
js

Now, call the loginUser() method inside the onClick handler of the <Button /> component inside the form.

1// ...
2<Button variant="primary" type="button" onClick={() => loginUser(this.state)}>
3  Submit
4</Button>
5// ...
jsx

The complete code for the component file is as follows.

1import React, { useState } from "react";
2import Form from "react-bootstrap/Form";
3import Button from "react-bootstrap/Button";
4
5const loginUser = async values => {
6  const res = await fetch({ url: SERVER_URL, method: "POST", body: values });
7  const data = await res.json();
8  return data;
9};
10
11class LoginForm extends Component {
12  state = {
13    email: "",
14    password: ""
15  };
16
17  handleChange = e => this.setState({ [e.target.name]: e.target.value });
18
19  render() {
20    return (
21      <Form>
22        <h2>Login</h2>
23        <hr />
24        <Form.Group controlId="formBasicEmail">
25          <Form.Label>Email address</Form.Label>
26          <Form.Control
27            type="email"
28            placeholder="Enter email"
29            onChange={this.handleChange}
30          />
31          <Form.Text className="text-muted">
32            We'll never share your email with anyone else.
33          </Form.Text>
34        </Form.Group>
35
36        <Form.Group controlId="formBasicPassword">
37          <Form.Label>Password</Form.Label>
38          <Form.Control
39            type="password"
40            placeholder="Password"
41            onChange={this.handleChange}
42          />
43        </Form.Group>
44        <Form.Group controlId="formBasicCheckbox">
45          <Form.Check type="checkbox" label="Check me out" />
46        </Form.Group>
47        <Button
48          variant="primary"
49          type="button"
50          onClick={() => loginUser(this.state)}
51        >
52          Submit
53        </Button>
54      </Form>
55    );
56  }
57}
58
59export default LoginForm;
jsx

There are two things to note here:

  1. It's best to pass the state keys explicitly inside the onClick handler rather than sending the whole state. You may end up giving the internal state to the method as you make future changes.
1<Button
2  variant="primary"
3  type="button"
4  onClick={() => {
5    const { email, password } = this.state;
6    loginUser({ email, password });
7  }}
8>
9  Submit
10</Button>
jsx
  1. You can only pass the whole state in a class-based component. Functional components have individual state variables that are created by the useState hook.

Conclusion

Now you understand the concept of state and how to pass state as props to other components or as a parameter to an external method. The key thing to remember is that it's always a best practice to explicitly pass individual state values instead of a whole state object.