componentDidMount是否等效于React函数/ Hooks组件?

时间:2018-12-27 13:18:45

标签: javascript reactjs react-hooks

有没有办法通过钩子在React功能组件中模拟componentDidMount

10 个答案:

答案 0 :(得分:12)

用于稳定版本的钩子(反应版本16.8.0 +)

对于componentDidMount

useEffect(() => {
    // Your code here
  }, []);

对于componentDidUpdate

useEffect(() => {
    // Your code here
  }, [yourDependency]);

对于componentWillUnmount

useEffect(() => {
    // componentWillUnmount
    return () => {
       // Your code here
    }
  }, [yourDependency]);

因此,在这种情况下,您需要将依赖项传递到此数组中。假设您处于这样的状态

const [count, setCount] = useState(0);

每当计数增加时,您都希望重新呈现功能组件。然后您的useEffect应该看起来像这样

useEffect(() => {
    // <div>{count}</div>
  }, [count]);

这样,只要您的计数更新,组件就会重新呈现。希望这会有所帮助。

答案 1 :(得分:3)

尽管接受的答案有效,但不建议这样做。当您有多个状态并将其与useEffect一起使用时,它将向您发出有关将其添加到依赖项数组或根本不使用它的警告。

有时会导致问题,可能会给您带来无法预测的输出。因此,我建议您花些力气将您的函数重写为类。更改几乎没有,您可以将某些组件作为类,而将某些组件作为函数。您没有义务只使用一种约定。

以这个为例

function App() {
  const [appointments, setAppointments] = useState([]);
  const [aptId, setAptId] = useState(1);

  useEffect(() => {
    fetch('./data.json')
      .then(response => response.json())
      .then(result => {
        const apts = result.map(item => {
          item.aptId = aptId;
          console.log(aptId);
          setAptId(aptId + 1);
          return item;
        })
        setAppointments(apts);
      });
  }, []);

  return(...);
}

class App extends Component {
  constructor() {
    super();
    this.state = {
      appointments: [],
      aptId: 1,
    }
  }

  componentDidMount() {
    fetch('./data.json')
      .then(response => response.json())
      .then(result => {
        const apts = result.map(item => {
          item.aptId = this.state.aptId;
          this.setState({aptId: this.state.aptId + 1});
          console.log(this.state.aptId);
          return item;
        });
        this.setState({appointments: apts});
      });
  }

  render(...);
}

这仅是示例。因此,不要谈论最佳实践或代码的潜在问题。两者都有相同的逻辑,但后者仅能按预期工作。您可能会在此时运行useEffect来获得componentDidMount功能,但是随着您的应用程序的增长,您可能会遇到一些问题。因此,与其在该阶段进行重写,不如在早期阶段进行重写。

此外,OOP还不错,如果面向过程的编程就足够了,那么我们就永远不会有面向对象的编程。有时会很痛苦,但会更好(从技术上讲,不包括个人问题)。

答案 2 :(得分:1)

是的,诸如componentDidMount之类的生命周期方法仅在类组件中可用。

即使在出现钩子之后,也不应将其视为过时的类组件,它们仍将是React的重要组成部分。

答案 3 :(得分:1)

您要使用useEffect(),它的作用取决于componentDidMount()。

例如。您可以使用一个自定义的loaded状态属性,该属性最初设置为false,然后在渲染时将其切换为true,并且仅在此值更改时才触发效果。

Documentation

答案 4 :(得分:0)

功能组件上没有componentDidMount,但是React Hooks提供了一种使用useEffect钩子来模拟行为的方式。

将空数组作为第二个参数传递给useEffect(),以仅在安装时运行回调。

请阅读documentation on useEffect

function ComponentDidMount() {
  const [count, setCount] = React.useState(0);
  React.useEffect(() => {
    console.log('componentDidMount');
  }, []);

  return (
    <div>
      <p>componentDidMount: {count} times</p>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        Click Me
      </button>
    </div>
  );
}

ReactDOM.render(
  <div>
    <ComponentDidMount />
  </div>,
  document.querySelector("#app")
);
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>

答案 5 :(得分:0)

componentDidMount()的确切等效钩子是

useEffect(()=>{},[]);

希望这会有所帮助:)

答案 6 :(得分:0)

react挂钩中没有与componentDidMount完全相同的内容。


以我的经验,反应挂钩在开发时需要不同的心态,通常来说,您不应将其与componentDidMount之类的类方法进行比较。

话虽如此,您可以通过多种方式使用钩子来产生与componentDidMount类似的效果

解决方案1:

useEffect(() => {
  console.log("I have been mounted")
}, [])

解决方案2:

const num = 5

useEffect(() => {
  console.log("I will only run if my deps change: ", num)
}, [num])

解决方案3(具有功能):

useEffect(() => {
  const someFunc = () => {
    console.log("Function being run after/on mount")
  }
  someFunc()
}, [])

解决方案4(useCallback):

const msg = "some message"

const myFunc = useCallback(() => {
  console.log(msg)
}, [msg])

useEffect(() => {
  myFunc()
}, [myFunc])

解决方案5(获得创意):

export default function useDidMountHook(callback) {
  const didMount = useRef(null)

  useEffect(() => {
    if (callback && !didMount.current) {
      didMount.current = true
      callback()
    }
  })
}

值得注意的是,只有在其他解决方案都不适合您的用例的情况下,才真正使用解决方案5 。如果您确定需要解决方案5,则建议使用此pre-made hook use-did-mount

来源(详细信息):Using componentDidMount in react hooks

答案 7 :(得分:0)

useEffect() 钩子允许我们实现 componentDidMount 的功能,componentDidUpdate componentWillUnMount 功能。

useEffect() 的不同语法允许实现上述每种方法。

i) componentDidMount

useEffect(() => {
  //code here
}, []);

ii) componentDidUpdate

useEffect(() => {
  //code here
}, [x,y,z]);

//where x,y,z are state variables on whose update, this method should get triggered

iii) componentDidUnmount

useEffect(() => {
  //code here
  return function() {
    //code to be run during unmount phase
  }
}, []);

您可以查看官方 react 站点以获取更多信息。 Official React Page on Hooks

答案 8 :(得分:0)

关于钩子内异步函数的信息:

Effect 回调是同步的,以防止竞争条件。把异步函数放在里面:

useEffect(() => {
  async function fetchData() {
    // You can await here
    const response = await MyAPI.getData(someId);
    // ...
  }
  fetchData();
}, [someId]); // Or [] if effect doesn't need props or state

答案 9 :(得分:0)

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

请访问此官方文档。很容易理解最新方式

https://reactjs.org/docs/hooks-effect.html