question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`useCallback()` & `useMemo()` automatically with a Babel Plug-in

See original GitHub issue

Do you want to request a feature or report a bug?

Feature request.

What is the current behavior?

We need to useCallback() and useMemo() which seems redundant and can cost us in performance if not used right, which is likely to happen.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn’t have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:

export default ({ data, sortComparator, filterPredicate, history }) => {
  const transformedData = data.filter(filterPredicate).sort(sortComparator)

  return (
    <div>
      <button className="back-btn" onClick={() => history.pop()} />
      <ul className="data-list">
        {transformedData.map(({ id, value }) => (
          <li className="data-item" key={id} onClick={() => history.push(`data/${id}`)}>{value}</li>
        ))}
      </ul>
    </div>
  )
}

What is the expected behavior?

Just like the docs suggest:

In the future, a sufficiently advanced compiler could create this array automatically.

Accordingly, I have implemented a Babel-plug-in that does exactly that; see babel-plugin-react-persist. Given the code snippet above, the plug-in should generate the following output:

let _anonymousFnComponent, _anonymousFnComponent2

export default ({ data, sortComparator, filterPredicate, history }) => {
  const transformedData = React.useMemo(() =>
    data.filter(filterPredicate).sort(sortComparator)
  , [data, data.filter, filterPredicate, sortComparator])

  return React.createElement(_anonymousFnComponent2 = _anonymousFnComponent2 || (() => {
    const _onClick2 = React.useCallback(() => history.pop(), [history, history.pop])

    return (
      <div>
        <button className="back-btn" onClick={_onClick2} />
        <ul className="data-list">
          {transformedData.map(({ id, value }) =>
            React.createElement(_anonymousFnComponent = _anonymousFnComponent || (() => {
              const _onClick = React.useCallback(() =>
                history.push(`data/${id}`)
              , [history, history.push, id])

              return (
                <li className="data-item" key={id} onClick={_onClick}>
                  {value}
                </li>
              )
            }), { key: id })
          )}
        </ul>
      </div>
    )
  }), null)
}

The plug-in will:

  • useCallback() automatically when a function is created.
  • useMemo() automatically when a value is assigned.
  • Will memoize inline callbacks.

I don’t see however how can useEffect() be inferred automatically and if it’s a good idea. The plug-in is not a feature request directly for React, but since it’s stated in the docs I thought maybe it can be useful somehow. Maybe it can potentially be included as part of create-react-app? Would like to hear your thoughts about it. An alternative solution is suggested at #14406, but I don’t see why do this at runtime when everything can be done ahead of time and save processing power.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

React 16.8-alpha (hooks)

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:13
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
DAB0mBcommented, Mar 10, 2019

@yuchi I’m just expecting to have a solution that works right out of the box. I don’t even wanna think about it. If a machine can do it better than me, why should I even bother? If there would be enough awareness for this plug-in and activity from the community, there would be almost non to no bugs. Of course there are bugs in what I created, but it’s only a proof of concept. About using let variable - you definitely can’t use useMemo(), my plug-in handles that pretty nicely, Everything is solvable with a smart enough plug-in.

1reaction
yuchicommented, Feb 7, 2019

I’m sorry but I think you misread the content of the issue #14406. No one is talking about runtime checks. Indeed I created hooks.macro which does the job at build time — it looks at runtime, but that’s the power of Babel macros.

Read more comments on GitHub >

github_iconTop Results From Across the Web

I wrote a Babel-Plug-in that will useCallback ... - Eytan Manor
I wrote a Babel-Plug-in that will useCallback() & useMemo() automatically, so you don't even need to think about it when implementing the ...
Read more >
A Babel-Plugin that will useCallback() & useMemo ... - Reddit
A Babel-Plugin that will useCallback() & useMemo() automatically and escape inline functions! r/reactjs - A Babel-Plugin that will ...
Read more >
babel-plugin-react-persist - npm package - Snyk
babel -plugin-react-persist. v0.2.0. Automatically useCallback() and useMemo() For more information about how to use this package see README.
Read more >
Babel plugin and get a performance boost for your React ...
sortComparator) } render() { return ( <div> <button onClick={this. ... team invented a couple of methods: useCallback() and useMemo() .
Read more >
Hooks API Reference - React
useReducer; useCallback; useMemo; useRef; useImperativeHandle ... method found in class components, useState does not automatically merge update objects.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found