skip to Main Content

In React, we can write components as pure functions. However, the problem with this is that you can’t use it as stateful components because of the lack of lifecycle hooks and state. So, I wonder if is there any way to create stateful components without using classes.

Something that I found is the createClass helper. But, React has moved this helper into their own package in the release 15.5.0, link. Also, they recommend that you migrate them to JavaScript classes because classes are now the preferred way to create components in React. Therefore, I don’t think that using this helper could be a good idea.

On the other hand, Facebook recommends the use of High Order Components (HOCs) which is an advanced technique in React for reusing component logic. HOCs are not part of the React API, per se. They are a pattern that emerges from React’s compositional nature. But, I couldn’t find a way to create common stateful components without classes.

Has anyone gone through this? Is there any way to use React as a some purely functional solution?

4

Answers


  1. Writing Stateful component without using classes is definitely a choice made by several developers. I recommend to use ‘recompose’ which has nice and easy implementation to write stateful components without class, yet apply state, both local and from store. Here is an example:

    import compose from 'recompose/compose'
    import withState from 'recompose/withState'
    import withProps from 'recompose/withProps'
    
    Pure.js
    
    function MyComponent(props) ({
    
      local: { prop1, prop2 },
      setProp1 
    })
    
      return <div>{prop1}</div>
    }
    
    const defaultState = {
      prop1: false,
      prop2: false
    }
    
    const enhance = compose(
      withState('local', 'updateLocal', defaultState),
      withProps(({ local: { prop1, prop2 }, updateLocal }) => ({
        setProp1: (newValue) => updateLocal(state => ({...state, prop1: newValue }))
      })))
    
    export default enhance(MyComponent)
    
    Login or Signup to reply.
  2. Maybe react-instance can become handy. Take a look at examples below.

    Save state in local variable:

    import React from "react"
    import instance from "react-instance"
    
    const App = instance(({ forceUpdate }) => {
      let time = 0
    
      const timer = setInterval(() => {
        time++
        forceUpdate()
      }, 100)
    
      return {
        render() {
          return time
        },
        unmount() {
          clearInterval(timer)
        },
      }
    })
    

    Save state in component state:

    import React from "react"
    import instance from "react-instance"
    
    const App = instance(instance => {
      instance.state = { time: 0 }
    
      const timer = setInterval(() => {
        instance.setState({ time: instance.state.time + 1 })
      }, 100)
    
      return {
        render() {
          return instance.state.time
        },
        unmount() {
          clearInterval(timer)
        },
      }
    })
    
    Login or Signup to reply.
  3. React supports this since version 16.8. From the documentation:

    Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.

    A simple example:

    import { useState } from 'react';
    
    function Example() {
      // Declare a new state variable, which we'll call "count"
      const [count, setCount] = useState(0);
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    

    For an example of how to use lifecycles, check out useEffect

    Login or Signup to reply.
  4. I tried to create a simple stateful component named Comp without the usage of es6 classes.

    Here is the code

    Basically I’m linking the prototype of the Comp function (our stateful component) to the prototype object of React.Component and I pass down to it Comp’s props to initialize it properly. After that you can use every function of the React.Component object on the Comp.prototype. I used some just an example. I don’t know if this is the best way in the “most javascript” way to use react

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search