是否可以componentDidMount
通过钩子在React功能组件中进行仿真?
Answers:
对于钩子的稳定版本(反应版本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]);
这样,无论何时更新计数,组件都将重新呈现。希望这会有所帮助。
useState
。对于阅读本文的任何人,请记住,离开第二个参数undefined
将导致您的效果在每次渲染时触发(如果我没记错的话)。
尽管可接受的答案有效,但不建议这样做。当您有多个状态并将其与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还不错,如果面向过程的编程就足够了,那么我们就永远不会有面向对象的编程。有时很痛苦,但更好(从技术上讲,不考虑个人问题)。
没有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>
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
您想使用useEffect()
,它取决于您使用该函数的方式,其作用类似于componentDidMount()。
例如。您可以使用loaded
最初设置为false的自定义状态属性,并在渲染时将其切换为true,并且仅在此值更改时才触发效果。