javascript - React useRef or module scope to store UI-independent state - Stack Overflow

Let's say there is a UI-independent state called currentSelected in React functional ponent. It st

Let's say there is a UI-independent state called currentSelected in React functional ponent. It stores the currently selected item and will be used at some time.

There are two ways to store the state, useRef hook or module scope out of ponent.

useRef hook:

function Example() {
  const currentSelected = useRef()

  useEffect(() => {
    // access currentSelected state
  })

  function handleClick(item) {
    currentSelected.current = item
  }

  return (
      <ul>
        {items.map(item => <li onClick={() => handleClick(item)}>item.name</li>)}
      </ul>
  )
}

module scope:

let currentSelected = null
function Example() {

  useEffect(() => {
    // access currentSelected state
  })

  function handleClick(item) {
    currentSelected = item
  }

  return (
      <ul>
        {items.map(item => <li onClick={() => handleClick(item)}>item.name</li>)}
      </ul>
  )
}

Which method is more suitable for storing UI-independent state like currentSelected?

And what is the application scenario of useRef and module scope in storing state?

========= Update ===========

UI-independence means that you don't want to trigger re-render after updating the state. In contrast, UI related states do this.

Let's say there is a UI-independent state called currentSelected in React functional ponent. It stores the currently selected item and will be used at some time.

There are two ways to store the state, useRef hook or module scope out of ponent.

useRef hook:

function Example() {
  const currentSelected = useRef()

  useEffect(() => {
    // access currentSelected state
  })

  function handleClick(item) {
    currentSelected.current = item
  }

  return (
      <ul>
        {items.map(item => <li onClick={() => handleClick(item)}>item.name</li>)}
      </ul>
  )
}

module scope:

let currentSelected = null
function Example() {

  useEffect(() => {
    // access currentSelected state
  })

  function handleClick(item) {
    currentSelected = item
  }

  return (
      <ul>
        {items.map(item => <li onClick={() => handleClick(item)}>item.name</li>)}
      </ul>
  )
}

Which method is more suitable for storing UI-independent state like currentSelected?

And what is the application scenario of useRef and module scope in storing state?

========= Update ===========

UI-independence means that you don't want to trigger re-render after updating the state. In contrast, UI related states do this.

Share Improve this question edited Apr 15, 2020 at 23:30 Emile Bergeron 17.4k5 gold badges85 silver badges131 bronze badges asked Jan 4, 2020 at 9:09 junlinjunlin 2,0452 gold badges29 silver badges40 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 12

The difference between useRef and a module-scope variable

Just for pleteness sake, I'll throw in useState as well.

  • useState: immutable data that's tied to the ponent instance and triggers render on change through the setter function.
  • useRef: mutable data that's also tied to the ponent instance, but doesn't trigger any renders on change.
  • A module scope variable: mutable data that's tied to the module, which also doesn't trigger any renders on change since it's pletely outside of React.

Use-case for useRef

If you're mounting a ponent more than once, e.g. using it on two pages, useRef will ensure that each ponent instance has its own mutable value.

// Here, the Example ponent could be used in multiple places
// and each instance would successfully keep its own state while
// not triggering renders on changes.
function Example() {
  const currentSelected = useRef()

  useEffect(() => { /* access currentSelected state */ })

  return (
      <ul>
        {items.map(item => (
          <li onClick={() => { currentSelected.current = item }}>{item.name}</li>
        ))}
      </ul>
  )
}

Use-case for a module scope variable

If you're looking for a singleton-like pattern or a static-like variable, e.g. for some kind of app-wide shared data, then a module scope variable will make this possible, like in any vanilla JS module.

// Here, the count value will be initialized once and then shared between every
// instances across the app, ever.

let count = 0;
function Example() {
  // Won't trigger a render, so some Example instance could still show the old value.
  count += 1;

  return <span>Combined renders of all the Example ponents: {count}</span>;
}

Note that it won't trigger a render when count changes, so you shouldn't use it like that.


The caveats

If used only once in a place where the ponent is also only mounted once, both patterns will appear to behave similarly, but in the end, it's a matter of time until something triggers a remount and then you'll be facing a weird bug.

You could also encounter problems when unit testing a module with a module scope variable in it since it may not be properly reset in-between test cases. A quick workaround is to just export the variable and let the test cases change its value, but be careful not to change it anywhere else. Though this should be evaluated as a case-by-case basis.

First one

For myself choose the first one.Because its works as individual inside function.You could use multiple example ponent as same class/function .

function check(a){
 let one = 'overwrite'+a;
 console.log(one)
}

check(1);
check(2);//as individual inside only

Second one

Its overwrite currentSelected variable on each example ponent execute

let one = null
//second one
function check() {
  one = 'overwrite';
  console.log(one)
}

console.log('Before =' + one)
check();
console.log('After =' + one);

why not use the useState hook. it's perfect for this secnario.

const [currentItem, setCurrentItem] = useState();
...
{items.map(item => <li onClick={() => setCurrentItem(item)}>item.name</li>)}

another problem with your example is that when you change the ref current property in the handleClick it doesnt triggered render, so the useEffect in your function will not run so you cant access the ref.

Your "currentItem" may be UI-independent, but it would be ponent-dependent. right? If currentItem is related to this ponent, you should use the React.useState hook. This is just what the state is for.

Global variables(not constants) should be avoided in OOP programming. For example, there would be only one global variable in well-written OOP code, i.e. theApp.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742362515a4429662.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信