DEV Community

Discussion on: React hooks & the closure hell

Collapse
 
anpos231 profile image
anpos231 • Edited

There is another way to go about this, maybe cleaner for some people.

const useSelfish = (load) => {
  const self = useRef(load)
  self.current.props = load.props
  self.current.state = load.state
  return [ self.current ]
}

It can be used like this (Try here):

const [ self ] = useSelfish({
    props: props,
    state: {
      value: useState(1)
    },
    handleClick: function() {
      const [ value, setValue ] = self.state.value
      setValue(value + 1)
    }
})

This version will be nicer for people who preferred old-school OOP programming. You've got the object, and you can set whatever you want there.

Example

import React, { useState, useRef, memo } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

const useSelfish = (load) => {
  const self = useRef(load)
  self.current.props = load.props
  self.current.state = load.state
  return [ self.current ]
}

let times = 0;

const ExpensiveComponent = memo(({ onClick }) => (
  <p onClick={onClick}>I am expensive form component: {times++}</p>
));

const App = (props) => {

  const [ self ] = useSelfish({
    props: props,
    state: {
      value: useState(1)
    },
    handleClick: function() {
      const [ value, setValue ] = self.state.value
      setValue(value + 1)
    }
  })

  const [ value ] = self.state.value

  console.log("Value: " + value);

  return (
    <div className="app">
      <ExpensiveComponent onClick={self.handleClick} />
      <button onClick={self.handleClick}>
        I will not trigger expensive re-render
      </button>
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Collapse
 
ntvinhit profile image
Nguyễn Trọng Vĩnh

How can I use effect in this?
Or just with normal useEffect with dependencies [self.state.value]?

Collapse
 
anpos231 profile image
anpos231

useEffect with dependencies [self.state.value]

Should work fine.

But I advise you try the new, cleaner version: dev.to/anpos231/react-hooks-the-cl...