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


Answers:


216

对于钩子的稳定版本(反应版本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]);

这样,无论何时更新计数,组件都将重新呈现。希望这会有所帮助。


彻底的解释!有没有一种方法可以模拟componentDidReceiveProps?
jeyko

1
即使它存在,我也不知道。您可以在github.com/facebook/react/issues/3279上
Mertcan Diken

1
谢谢您,因为我不知道中的第二个参数useState。对于阅读本文的任何人,请记住,离开第二个参数undefined将导致您的效果在每次渲染时触发(如果我没记错的话)。
dimiguel

您是指useEffect的依赖项(传递依赖项数组)吗?如果是这样,那么如果您将其保留为空,那是代码中的错误。对于数组解构,您都需要[count,setCount],因为在此示例中count是您的状态变量,而setCount是用于更新该状态的函数。
Mertcan Diken

1
我一直在尝试使用空的依赖项数组来模拟componentDidMount。问题在于,它通常会导致警告:“ React Hook useEffect缺少依赖项:<some prop>。要么包含它,要么删除依赖项数组react-hooks / exhaustive-deps”。应用任何建议的“修补程序”将使其不再充当componentDidMount。难道我做错了什么?
乔纳斯·罗森奎斯特

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还不错,如果面向过程的编程就足够了,那么我们就永远不会有面向对象的编程。有时很痛苦,但更好(从技术上讲,不考虑个人问题)。


1
我做到了 我在使用钩子时遇到问题。将其转换为类后,问题不再存在。
Julez

2

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

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

请阅读上的文档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>


1

componentDidMount在React钩子中没有确切的等效项。


以我的经验,反应挂钩在开发时需要不同的心态,通常来说,您不应将其与类方法进行比较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,那么我建议使用此预制的钩子use-did-mount

来源(有更多详细信息):在react挂钩中使用componentDidMount


0

componentDidMount()的确切等效钩子是

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

希望对您有所帮助:)


-1

您想使用useEffect(),它取决于您使用该函数的方式,其作用类似于componentDidMount()。

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

文献资料


1
该解决方案不是理想的。仅使用状态值来确定组件是否已安装是一个坏主意。另外,如果要使用属性,则ref会更好,因为它不会触发其他重新渲染。
Yangshun Tay
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.