【问题标题】:What is the right place to call a function before render in React?在 React 中渲染之前调用函数的正确位置是什么?
【发布时间】:2020-10-04 10:21:05
【问题描述】:

我在理解 React 中的生命周期时遇到了一些问题,所以我使用 useEffects() 因为我明白这是在组件呈现之前调用方法的正确方法(替换 componentDidMount )。

  useEffect(() => {
    tagSplit = tagArr.split(',');
  });

然后我在组件上调用 tagSplit.map() 函数,但它说 tagSplit.map 不是函数

{tagSplit.map((item, index) => (
   <div className="styles" key={index}>
      {item}
   </div>
))}

有什么问题需要我修复还是正常?

【问题讨论】:

    标签: reactjs components react-hooks render lifecycle


    【解决方案1】:

    useEffect 在渲染之后运行,然后随着依赖关系的变化而运行。

    所以是的,如果你有 tagSplit 作为最初不支持 map 函数的东西,它会在第一次渲染时给你一个错误。

    如果你想控制它运行的次数,你应该提供一个依赖数组。

    来自docs

    useEffect 是否在每次渲染后运行?是的!默认情况下,它会在第一次渲染后和每次更新后运行。 (我们稍后会讨论如何自定义它。)与其考虑“安装”和“更新”,您可能会发现更容易认为效果发生在“渲染后”。 React 保证 DOM 在运行效果时已经更新。

    来自 Dan Abramov 博客的This article 也应该有助于更好地理解useEffect

    const React, { useState, useEffect } from 'react'
    
    export default () => {
      const [someState, setSomeState] = useState('')
    
      // this will get reassigned on every render
      let tagSplit = ''
    
      useEffect(() => {
        // no dependencies array,
        // Runs AFTER EVERY render
        tagSplit = tagArr.split(',');
      })
    
      useEffect(() => {
        // empty dependencies array
        // RUNS ONLY ONCE AFTER first render
      }, [])
    
    
      useEffect(() => {
        // with non-empty dependency array
        // RUNS on first render 
        // AND AFTER every render when `someState` changes
      }, [someState])
    
      return (
        // Suggestion: add conditions or optional chaining
        {tagSplit && tagSplit.map
            ? tagSplit.map((item, index) => (
                <div className='styles' key={index}>
                  {item}
                </div>
              ))
            : null}
      )
    }
    

    【讨论】:

      【解决方案2】:

      你可以这样做。

      function App() {
      
          const [arr, setArr] = useState([]);
      
          useEffect(() => {
              let tagSplit = tagArr.split(',');
              setArr(tagSplit);
          }, []);
      
          return (
              <>
                  {arr.map((item, index) => (
                      <div className="styles" key={index}>
                          {item}
                      </div>
                  ))}
              </>
          )
      }
      

      【讨论】:

      • 我已经尝试过这个并且成功了,但是它在渲染中调用了 100 次并且使我的页面如此滞后,这怎么可能?
      • @Faishal 如果这对您的问题有帮助,请考虑将此答案标记为!!
      猜你喜欢
      • 2019-07-06
      • 1970-01-01
      • 2019-08-20
      • 2019-02-21
      • 2021-10-16
      • 2020-08-07
      • 2014-12-08
      • 1970-01-01
      • 2021-07-20
      相关资源
      最近更新 更多