React: Performance Optimization: useMemo and useCallback

Last updated: 2026-08-26

1. What You'll Learn



2. The Story of a Search Filter Page

The Relationship Among the Three Components of Performance Optimization

100%
flowchart TD
    A[Parent Component Rendering] --> B{Props It's changed?}
    B -->|Yes| C[React.memo Intercept?]
    B -->|No| D[Skip subcomponents ✅]
    C -->|A rough comparison is roughly equal| D
    C -->|Shallow Comparison Inequality| E{Function/The object is new.?}
    E -->|Yes| F[useCallback/useMemo]
    F --> G[Stable Citation → memo Effective ✅]
    E -->|No| D
    
    style F fill:#e8f5e9,stroke:#2e7d32
    style D fill:#c8e6c9,stroke:#2e7d32
    style G fill:#c8e6c9,stroke:#2e7d32

(1) Pain Point: Recalculation with Every Input

Alice created a product search page with 10,000 products to filter through:

JSX
function ShopPage() {
  const [products] = useState(generate10000Products())
  const [search, setSearch] = useState('')
  const [sortBy, setSortBy] = useState('name')

  // ❌ Question:Re-filter after each input 10,000 Items
  const filtered = products
    .filter(p => p.name.includes(search))
    .sort((a, b) => a[sortBy] > b[sortBy] ? 1 : -1)

  return (
    <div>
      <input value={search} onChange={e => setSearch(e.target.value)} />
      <select value={sortBy} onChange={e => setSortBy(e.target.value)}>
        <option value="name">By Name</option>
        <option value="price">By Price</option>
      </select>
      <ProductList products={filtered} />
    </div>
  )
}
▶ Try it Yourself

Issue: Every time the keyboard input (setSearch) is entered, it triggers filter and sort to run again—10,000 records have to be filtered each time, causing the interface to lag.

(2) The useMemo Solution

JSX
function ShopPage() {
  const [products] = useState(generate10000Products())
  const [search, setSearch] = useState('')
  const [sortBy, setSortBy] = useState('name')

  // ✅ useMemo:Only at search or  sortBy Recalculate only when there is a change
  const filtered = useMemo(() => {
    console.log('Refilter...(Only when the search terms or sorting criteria change)')
    return products
      .filter(p => p.name.includes(search))
      .sort((a, b) => a[sortBy] > b[sortBy] ? 1 : -1)
  }, [search, sortBy, products])

  return (
    <div>
      <input value={search} onChange={e => setSearch(e.target.value)} />
      <select value={sortBy} onChange={e => setSortBy(e.target.value)}>
        <option value="name">By Name</option>
        <option value="price">By Price</option>
      </select>
      <ProductList products={filtered} />
    </div>
  )
}
▶ Try it Yourself

Benefits: Filtering is only re-run when the input changes to either search or sortBy; other state changes (such as the parent component being re-rendered) do not trigger filtering, resulting in a 10- to 100-fold performance improvement.



3. useMemo: Caching Calculation Results

Hook What to remember Return value When dependencies change
useMemo Calculation Result Cached Value Recalculate
useCallback Function References Cached Functions Creating New Functions
React.memo Rendered result of the entire component Skip re-rendering Re-render when props change

(1) Basic Syntax

JSX
const memoizedValue = useMemo(() => {
  return Costly Computations()
}, [Dependency1, Dependency2])
▶ Try it Yourself
Section Description
() => Computation A function that needs to be cached and returns the result of the calculation
[Dependencies] Recalculate when dependencies change
memoizedValue Cached results (returns the previous result directly if dependencies haven't changed)

(2) Applicable Scenarios

JSX
// Scene 1:Data Conversion(Filter、Sort、Grouping)
const activeUsers = useMemo(
  () => users.filter(u => u.isActive).sort((a, b) => a.name.localeCompare(b.name)),
  [users]
)

// Scene 2:Format(Numbers、Date、String Concatenation)
const formattedPrice = useMemo(
  () => new Intl.NumberFormat('zh-CN', { style: 'currency', currency: 'CNY' }).format(price),
  [price]
)

// Scene 3:Derived State(Calculating New Data from Existing Data)
const statistics = useMemo(() => ({
  total: orders.length,
  paid: orders.filter(o => o.status === 'paid').length,
  amount: orders.reduce((sum, o) => sum + o.amount, 0),
  avgAmount: orders.length ? orders.reduce((sum, o) => sum + o.amount, 0) / orders.length : 0
}), [orders])
▶ Try it Yourself

▶ Example: Performance Comparison

Output:

TEXT 📖 Display only
...
JSX
// ============================================
// Example:useMemo vs no useMemo Performance Comparison
// ============================================

function ExpensiveCalc({ num, unrelated }) {
  // ❌ None useMemo:Executed on every render
  const slowResult1 = slowFibonacci(num)

  // ✅ With useMemo: num If it hasn't changed, don't recalculate it.
  const slowResult2 = useMemo(() => slowFibonacci(num), [num])

  return (
    <div>
      <p>num={num} The Fibonacci sequence</p>
      <p>Without useMemo: {slowResult1}(Rendering calculations each time)</p>
      <p>With useMemo: {slowResult2}(Only at num Calculate when changes occur)</p>
      <p>Unrelated Status:{unrelated}(Click the button to change this value)</p>
    </div>
  )
}

function slowFibonacci(n) {
  if (n <= 1) return n
  let a = 0, b = 1, c
  for (let i = 2; i <= n; i++) { c = a + b; a = b; b = c }
  console.log('fibonacci Calculation!n=' + n)
  return b
}
// Click to Make a Difference unrelated → without useMemo recalculates,with useMemo skips
▶ Try it Yourself

Output:

TEXT 📖 Display only
Fibonacci(n): without useMemo recalculates every render, with useMemo skips when only unrelated state changes. Console: "fibonacci calculated! n=X"


4. useCallback: Remembering Function References

(1) Basic Syntax

JSX
const memoizedFn = useCallback(() => {
  doSomething(a, b)
}, [a, b])
▶ Try it Yourself

useCallback(fn, deps) is equivalent to useMemo(() => fn, deps) — what is stored is the function itself, not the result of the function.

(2) Why is useCallback needed?

JSX
function Parent() {
  const [count, setCount] = useState(0)

  // ❌ Every time Parent Rendering,handleClick These are all new functions
  // resulting in Child 's  React.memo Failure
  const handleClick = () => {
    console.log('Clicked')
  }

  // ✅ useCallback:handleClick Citation unchanged
  // Child 's  React.memo Works properly(Skip Re-rendering)
  const handleClick = useCallback(() => {
    console.log('Clicked')
  }, [])  // Empty Dependency:This function will never change.
}
▶ Try it Yourself

(3) React.memo: Preventing Child Components from Rendering Again

JSX
// ============================================
// Example:useCallback + React.memo For use in combination with
// ============================================

// ---- Child component:use  React.memo Package ----
const ExpensiveList = React.memo(function ExpensiveList({ items, onItemClick }) {
  console.log('ExpensiveList Render Again!')
  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>
          {item.name}
          <button onClick={() => onItemClick(item.id)}>Select</button>
        </li>
      ))}
    </ul>
  )
})

// ---- Parent Component ----
function App() {
  const [count, setCount] = useState(0)
  const [items] = useState([
    { id: 1, name: 'Project A' },
    { id: 2, name: 'Project B' },
    { id: 3, name: 'Project C' }
  ])

  // ❌ Every time App Rendering,All function references have changed → React.memo Failure
  const handleClickBad = (id) => console.log('Select:', id)

  // ✅ Function references are immutable → React.memo Effective
  const handleClick = useCallback((id) => {
    console.log('Select:', id)
  }, [])

  return (
    <div>
      <p>Counter:{count}</p>
      <button onClick={() => setCount(c => c + 1)}>Change Count</button>
      {/* Tap the button to change the count → No impact ExpensiveList Rendering of */}
      <ExpensiveList items={items} onItemClick={handleClick} />
    </div>
  )
}
// When clicking "Change Count" :
// ❌ Without useCallback → ExpensiveList Render again
// ✅ has  useCallback → ExpensiveList Skip rendering(Performance Improvements)
▶ Try it Yourself

5. When to Use It, and When Not to Use It

(1) When to Use It

Scenario Hook Reason
Big Data Filtering/Sorting useMemo Avoid traversing large amounts of data on every render
Complex Calculations (Math/Formatting) useMemo No need to recalculate if the result remains the same
Passing props to a React.memo child component useCallback Keeping function references stable so that React.memo works
Functions in useEffect Dependencies useCallback Preventing useEffect from Running Multiple Times Due to Changes in Function References

(2) Situations Where It Is Not Needed

JSX
// ❌ Not necessary:Simple Calculations
const doubled = useMemo(() => count * 2, [count])
// ✅ Write it directly:count * 2 It's already pretty fast as it is
const doubled = count * 2

// ❌ Not necessary:Handle events without passing them to child components
const handleClick = useCallback(() => {
  console.log('Click')
}, [])
// ✅ Just write it down.
const handleClick = () => console.log('Click')

// ❌ Not necessary:The child component isn't being used. React.memo
// useCallback It's been packaged, but no one is buying it."Stable Citation"
▶ Try it Yourself

(3) The Cost of Abuse

JSX
// useMemo and  useCallback It involves expenses(Relies heavily on arrays)
// Abuse = Introducing Additional Comparison Logic,Slower than if it weren't optimized

// Rule of thumb:
// 1. First, let's write the version without optimization.
// 2. Feeling some lag(fps < 60)Use again
// 3. use  React DevTools Profiler Measurement
▶ Try it Yourself

6. Complete Example: Message List in a Chat App

JSX
// ============================================
// Complete Example:Chat Message List(Comprehensive Performance Optimization)
// ============================================

import { useState, useMemo, useCallback, memo } from 'react'

// ---- News Item(React.memo + useCallback) ----
const MessageItem = memo(function MessageItem({ message, onReact, onReply }) {
  console.log(`Rendering Message:${message.id}`)
  
  return (
    <div style={{
      padding: '12px',
      margin: '8px 0',
      backgroundColor: message.isMine ? '#e6f7ff' : '#f5f5f5',
      borderRadius: '8px'
    }}>
      <div style={{ display: 'flex', justifyContent: 'space-between' }}>
        <strong>{message.author}</strong>
        <span style={{ color: '#999', fontSize: '12px' }}>
          {message.time}
        </span>
      </div>
      <p style={{ margin: '8px 0' }}>{message.text}</p>
      <div style={{ display: 'flex', gap: '8px' }}>
        <button onClick={() => onReact(message.id)} style={smallBtn}>
          👍 {message.reactions}
        </button>
        <button onClick={() => onReply(message.id)} style={smallBtn}>
          💬 Reply
        </button>
      </div>
    </div>
  )
})

// ---- Main Component ----
function ChatApp() {
  const [messages, setMessages] = useState(generateMessages(100))
  const [filter, setFilter] = useState('All')
  const [unreadCount, setUnreadCount] = useState(5)

  // useMemo:Filter Messages(100 Filter by row)
  const filteredMessages = useMemo(
    () => filter === 'All'
      ? messages
      : messages.filter(m => filter === 'My' ? m.isMine : !m.isMine),
    [messages, filter]
  )

  // useCallback:Keep References Consistent,let  MessageItem 's  memo Effective
  const handleReact = useCallback((id) => {
    setMessages(prev => prev.map(m =>
      m.id === id ? { ...m, reactions: m.reactions + 1 } : m
    ))
  }, [])

  const handleReply = useCallback((id) => {
    console.log('Reply to a message:', id)
  }, [])

  // Calculate Statistical Information
  const stats = useMemo(() => ({
    total: messages.length,
    mine: messages.filter(m => m.isMine).length,
    totalReactions: messages.reduce((s, m) => s + m.reactions, 0)
  }), [messages])

  return (
    <div style={{ maxWidth: '600px', margin: '0 auto' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <h2>💬 Chat({unreadCount} Unread posts)</h2>
        <button onClick={() => setUnreadCount(c => c + 1)}>
          Increase the unread count(Test Performance)
        </button>
      </div>

      {/* Statistics(useMemo) */}
      <div style={{ display: 'flex', gap: '16px', marginBottom: '12px', fontSize: '13px', color: '#666' }}>
        <span>Total {stats.total} items</span>
        <span>My {stats.mine} items</span>
        <span>👍 {stats.totalReactions}</span>
      </div>

      {/* Filter Button */}
      <div style={{ marginBottom: '12px' }}>
        {['All', 'My', 'Other people's'].map(f => (
          <button
            key={f}
            onClick={() => setFilter(f)}
            style={{
              padding: '4px 12px', margin: '0 4px',
              backgroundColor: filter === f ? '#1890ff' : '#f0f0f0',
              color: filter === f ? 'white' : '#333',
              border: 'none', borderRadius: '4px', cursor: 'pointer'
            }}
          >
            {f}
          </button>
        ))}
      </div>

      {/* News List */}
      <div style={{ maxHeight: '500px', overflow: 'auto' }}>
        {filteredMessages.map(msg => (
          <MessageItem
            key={msg.id}
            message={msg}
            onReact={handleReact}   // ✅ Stable citation
            onReply={handleReply}   // ✅ Stable citation
          />
        ))}
      </div>
    </div>
  )
}

function generateMessages(count) {
  const names = ['Alice', 'Bob', 'Charlie', 'Diana']
  return Array.from({ length: count }, (_, i) => ({
    id: i + 1,
    author: names[i % 4],
    text: `This is the ${i + 1} The content of the message`,
    time: `${String(10 + i % 8).padStart(2, '0')}:${String(i % 60).padStart(2, '0')}`,
    isMine: i % 3 === 0,
    reactions: Math.floor(Math.random() * 5)
  }))
}

const smallBtn = {
  padding: '2px 8px', fontSize: '12px',
  border: '1px solid #d9d9d9', borderRadius: '4px',
  backgroundColor: 'white', cursor: 'pointer'
}

Expected Output: A chat list with 100 messages. When you click "Increase Unread Count," the message list will not re-render (no output in the console) due to useCallback and React.memo; only the count will change.


▶ Example 2: useCallback prevents useEffect from running multiple times

Output:

TEXT 📖 Display only
... ('fibonacci Calculation!n=' + n)
JSX
// ============================================
// Example:useCallback In conjunction with useEffect Avoiding Infinite Loops
// Features:Display useCallback in  useEffect The Key Role of Dependencies
// ============================================

import { useState, useEffect, useCallback } from 'react'

function SearchComponent() {
  const [query, setQuery] = useState('')
  const [results, setResults] = useState([])
  const [page, setPage] = useState(1)

  // ❌ Question:Each render is a new function,As useEffect Dependencies can cause an infinite loop
  // const fetchResults = async () => {
  //   const res = await fetch(`/api/search?q=${query}&page=${page}`)
  //   const data = await res.json()
  //   setResults(data)
  // }

  // ✅ Resolve:useCallback Stable Function References
  const fetchResults = useCallback(async () => {
    // Simulation API Request
    const mockData = [
      { id: 1, title: `Results ${query} - Page ${page}` },
      { id: 2, title: `Related Articles About ${query}` },
      { id: 3, title: `${query} Best Practices` }
    ]
    setResults(mockData)
  }, [query, page])  // query or  page Create a new function only when there is a change

  // Dependency fetchResults(Stable Citation,It won't go into an infinite loop)
  useEffect(() => {
    if (query.trim()) {
      fetchResults()
    }
  }, [fetchResults])  // fetchResults Citation unchanged → useEffect Will not be executed again

  return (
    <div style={{ maxWidth: '500px', margin: '0 auto' }}>
      <h2>🔍 Search(useCallback Demo)</h2>
      <input
        value={query}
        onChange={e => setQuery(e.target.value)}
        placeholder="Enter a search term..."
        style={{ width: '100%', padding: '8px', border: '1px solid #d9d9d9', borderRadius: '4px' }}
      />
      <div style={{ marginTop: '8px', display: 'flex', gap: '8px', alignItems: 'center' }}>
        <button onClick={() => setPage(p => Math.max(1, p - 1))} disabled={page <= 1}>Previous Page</button>
        <span>Page  {page} </span>
        <button onClick={() => setPage(p => p + 1)}>Next Page</button>
      </div>
      <ul style={{ marginTop: '12px', listStyle: 'none', padding: 0 }}>
        {results.map(r => (
          <li key={r.id} style={{ padding: '8px', borderBottom: '1px solid #f0f0f0' }}>
            {r.title}
          </li>
        ))}
      </ul>
      {!query && <p style={{ color: '#999', textAlign: 'center' }}>Enter a keyword to start your search</p>}
    </div>
  )
}

Output:

TEXT 📖 Display only
Search box + pagination. Type "React" → 3 results ("Results React - Page 1", etc.). useCallback prevents infinite useEffect loop. Prev/Next buttons.

▶ Example 3: Using useMemo to Implement Virtual List Calculations

Output:

TEXT 📖 Display only
Subheading: "🔍 Search(useCallback Demo)". Displays: "🔍 Search(useCallback Demo)". State: query (setter: setQuery), results (setter: setResults), page (setter: setPage). Button: setPage(p => p + 1)}>Next Page. Input: Enter a search term.... List: {r.title}. useEffect manages side effects. useCallback memoizes handler. Async data fetching/loading states
JSX
function VirtualList({ items, itemHeight = 40, visibleHeight = 400 }) {
  const [scrollTop, setScrollTop] = useState(0)

  const visibleCount = Math.ceil(visibleHeight / itemHeight)
  const totalHeight = useMemo(() => items.length * itemHeight, [items.length, itemHeight])

  const { startIndex, endIndex, offsetY } = useMemo(() => {
    const start = Math.floor(scrollTop / itemHeight)
    const end = Math.min(start + visibleCount + 1, items.length)
    return { startIndex: start, endIndex: end, offsetY: start * itemHeight }
  }, [scrollTop, itemHeight, visibleCount, items.length])

  const visibleItems = useMemo(() => items.slice(startIndex, endIndex), [items, startIndex, endIndex])

  return (
    <div onScroll={e => setScrollTop(e.currentTarget.scrollTop)}
      style={{ height: visibleHeight, overflowY: 'auto', border: '1px solid #ddd', borderRadius: 4 }}>
      <div style={{ height: totalHeight, position: 'relative' }}>
        <div style={{ position: 'absolute', top: offsetY, width: '100%' }}>
          {visibleItems.map((item, i) => (
            <div key={startIndex + i} style={{ height: itemHeight, padding: '0 12px', display: 'flex', alignItems: 'center', borderBottom: '1px solid #f0f0f0' }}>
              Row {startIndex + i}: {item}
            </div>
          ))}
        </div>
      </div>
    </div>
  )
}
▶ Try it Yourself

Output:

TEXT 📖 Display only
Virtual scroll: renders only visible rows (~10 of 1000+). Scroll → rows swap. Total height = items × 40px. useMemo computes visible range.

▶ Example 4: Optimizing Lists with React.memo + useCallback

Output:

TEXT 📖 Display only
Displays: "items.slice(startIndex, endIndex), [items, startIndex, endIn". State: scrollTop (setter: setScrollTop). useMemo optimizes computation
JSX
const ListItem = React.memo(function ListItem({ name, price, onRemove }) {
  console.log(`Rendering: ${name}`)
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', padding: 8, borderBottom: '1px solid #f0f0f0' }}>
      <span>{name} - ${price}</span>
      <button onClick={() => onRemove(name)} style={{ color: '#ff4d4f', border: 'none', cursor: 'pointer' }}>Remove</button>
    </div>
  )
})

function ProductList() {
  const [products, setProducts] = useState([
    { name: 'Keyboard', price: 79 },
    { name: 'Mouse', price: 49 },
    { name: 'Monitor', price: 399 },
    { name: 'Headphones', price: 129 },
  ])
  const [filter, setFilter] = useState('')

  const handleRemove = useCallback((name) => {
    setProducts(prev => prev.filter(p => p.name !== name))
  }, [])

  const filtered = useMemo(() => products.filter(p => p.name.toLowerCase().includes(filter.toLowerCase())), [products, filter])

  return (
    <div style={{ maxWidth: 400, margin: '0 auto' }}>
      <input value={filter} onChange={e => setFilter(e.target.value)} placeholder="Filter..." style={{ width: '100%', padding: 8, marginBottom: 8, borderRadius: 4 }} />
      {filtered.map(p => <ListItem key={p.name} name={p.name} price={p.price} onRemove={handleRemove} />)}
    </div>
  )
}
▶ Try it Yourself

Output:

TEXT 📖 Display only
Product list (Keyboard $79, Mouse $49, Monitor $399, Headphones $129) with filter. "Remove" deletes item. React.memo + useCallback = only changed items re-render.

▶ Example 5: When Not to Use useMemo—Anti-Pattern Comparison

Output:

TEXT 📖 Display only
Rendering: ...
JSX
function BadExample({ count }) {
  // ❌ Simple calculations are not required useMemo——Create memo Expenses > The Calculation Itself
  const doubled = useMemo(() => count * 2, [count])
  // ✅ Direct Calculation
  const doubledOk = count * 2

  // ❌ Each render creates a new object as useMemo Dependency
  const config = useMemo(() => ({ count }), [count])
  const badResult = useMemo(() => config.count * 3, [config]) // config A new reference each time!
  // ✅ Using Primitive Types Directly as Dependencies
  const goodResult = useMemo(() => count * 3, [count])

  return <p>Doubled: {doubledOk}, Tripled: {goodResult}</p>
}

function GoodExample({ items, query }) {
  // ✅ Filter/Sorting large amounts of data useMemo
  const filtered = useMemo(() => {
    return items.filter(item =>
      item.name.toLowerCase().includes(query.toLowerCase())
    ).sort((a, b) => a.name.localeCompare(b.name))
  }, [items, query])

  // ✅ Complex objects passed to child components use useMemo
  const chartData = useMemo(() => ({
    labels: filtered.map(i => i.name),
    values: filtered.map(i => i.price),
  }), [filtered])

  return (
    <div>
      <p>Found: {filtered.length} items</p>
      <Chart data={chartData} />
    </div>
  )
}
▶ Try it Yourself

Output:

TEXT 📖 Display only
❌ useMemo for count*2 (overhead > calculation). ❌ New object as dep breaks memo. ✅ useMemo for large filter/sort + derived chart data objects.

❓ FAQ

Q Do useMemo and useCallback always improve performance?
A Not necessarily. They come with their own overhead—they compare the dependencies array on every render. Overusing them can actually slow things down. React’s official recommendation: Start by writing the unoptimized version, and only optimize when you notice lag. Rule of thumb: Use them only for calculations passed to a React.memo child component or those with an overhead greater than 1 ms.
Q What is the difference between useMemo and a regular variable?
A useMemo has "memory"—if the dependencies haven’t changed, it uses the cached value directly without re-evaluating the expression. A regular variable is re-evaluated on every render. However, useMemo needs to compare the array of dependencies during rendering, so "simple calculations are actually slower with useMemo."
Q When should you use useCallback to preserve a function reference?
A You only need to use it when both of the following conditions are met: ① The function is passed as a prop to a React.memo child component; ② The function is in the dependencies array of a useEffect hook. If neither of these conditions applies, you can simply write the function directly; useCallback is unnecessary.
Q What is the difference between useMemo and useCallback?
A useMemo(() => value, deps) caches the result (value) of a calculation, while useCallback(() => fn, deps) caches a function reference. In fact, useCallback(fn, deps) is equivalent to useMemo(() => fn, deps). Use useCallback when you need to cache a function passed to a child component; use useMemo when you need to cache a computation result.

📖 Summary


📝 Exercises

  1. Basic Problem (Difficulty ⭐): Create a PrimeCalculator component that takes a number n as input and calculates the nth prime number. Use useMemo to cache the result so it isn't recalculated every time a new value is entered.
  2. Advanced Exercise (Difficulty ⭐⭐): Create a ProductTable component that contains 500 product records and supports filtering by category and sorting by price. Use useMemo to optimize the filtering and sorting logic, and use useCallback combined with React.memo to optimize list rendering.
  3. Challenge (Difficulty: ⭐⭐⭐): Create a DataDashboard component that aggregates 10,000 order records across three different dimensions (time, region, and category), and use useMemo to implement hierarchical caching (so that only the relevant layers are recalculated when the dimensions change).
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏