Los Morales
Los Morales

Reputation: 2155

React way to "setState" in a pure ES2015 function

React newb here. I have a pure function that returns a form (presentation component). In this form I need to handle onChange events for those text fields that are controlled. FWIU, I need to this.setState(...) in my onChange event handlers. However due to this being a pure function, I don't have access to this.setState(). Is there a nice way to set the state on these onChange events in a ES2015 function? I'm also using redux if this helps. Example code:

import React, {PropTypes} from 'react'

const ApplicationForm = ({submitHandler, person}) => (
<form onSubmit={e => submitHandler(e)}>
 <div>
            <label htmlFor="firstName">First Name:</label>
            <input type="text" name="firstName" onChange={e => setState(e.target.value)} value={person.firstName || ''}/>
 </div>
...
</form>
)

Upvotes: 5

Views: 9723

Answers (5)

Sarthak Mehra
Sarthak Mehra

Reputation: 43

With React Hooks, we now have state usability extended to functional components as well. To use this, we can import {useState} from React and pass default value into its arguments.

    import React, {PropTypes, useState} from 'react'
    
    const ApplicationForm = ({submitHandler, person}) => (
        
    const [name, updateName]= useState(person.firstName);


    <form onSubmit={e => submitHandler(e)}>
         <div>`enter code here`
                    <label htmlFor="firstName">First Name:</label>
                    <input type="text" name="firstName" onChange={e => updateName(e.target.value)} value={name || ''}/>
         </div>
        ...
        </form>
        )

More details about this can be found in the documentation for useState.

Upvotes: 1

Lakshan Enosh
Lakshan Enosh

Reputation: 219

You can use react hooks to achieve what you want.

If you write a function component and you want to add some sate to your function, previously you had to change your function into a class. But now you can use react hooks to create your state in your functional component.

EX:- We write class components with state as below

class Foo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      age: 20
    };
  }

now we can achieve above code in function component as followed

import React, { useState } from 'react';

function Foo() {
  const [age, setAge] = useState(20);

Refer this document for more details - https://reactjs.org/docs/hooks-state.html

Upvotes: 1

Jacquen
Jacquen

Reputation: 1126

You can actually use setState in something that looks like a functional component, but it's pretty hacky. I imagine this method is something only people who really can't stand using the this keyword and class syntax would ever use. Still, I think it's kind of fun.

Here's how you might write an input that changes another element in a normal way using this and class syntax:

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {text: "Hello, world"};
    }

    handleChange = (event) => {
        this.setState({text: event.target.value});
    }

    render() {
        return (
            <div>
                <input value={this.state.text} onChange={this.handleChange} />
                <h1>{this.state.text}</h1>
            </div>
        )
    }
}

And here's how you could create the same effect without this and class syntax:

function App() {
    "use strict";

    const obj = {
        state: {text: "Hello, world"},
        __proto__: React.Component.prototype
    };

    obj.handleChange = function (event) {
        obj.setState({text: event.target.value});
    };

    obj.render = function () {
        return (
            <div>
                <input value={obj.state.text} onChange={obj.handleChange} />
                <h1>{obj.state.text}</h1>
            </div>
        );
    };

    return obj;
}

The trick is to make the App function inherit from React.Component by setting the dunder proto property of the object App returns to React.Component's prototype so that it can use setState.

Here's a codepen if you want to play around with the code.

Upvotes: 2

Joe Attardi
Joe Attardi

Reputation: 4521

Stateless functional components can't have state... because they're stateless. If you want to have event handlers to call and state to set, you will need to create a component class, either via React.createClass or by using ES6 classes.

Upvotes: 1

CheapSteaks
CheapSteaks

Reputation: 5019

That is a Stateless Function, there is no state to set

If you're using redux, you probably want to trigger a redux action in the onChange, passing the new value as an argument, and have the action update the value of firstName in the redux store for person.firstName

I would recommend taking a look at redux-form to reduce a bunch of boilerplate

Upvotes: 9

Related Questions