มีวิธีในการจำลองcomponentDidMount
องค์ประกอบการทำงานของปฏิกิริยาผ่านตะขอหรือไม่?
มีวิธีในการจำลองcomponentDidMount
องค์ประกอบการทำงานของปฏิกิริยาผ่านตะขอหรือไม่?
คำตอบ:
สำหรับ hooks เวอร์ชันเสถียร (React Version 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]);
This way whenever your count updates your component will re-render. Hopefully this will help a bit.
useState
. To anyone reading this, please keep in mind that leaving the second argument undefined
will cause your effect to trigger on every render (if I'm not mistaken).
Although accepted answer works, it is not recommended. When you have more than one state and you use it with useEffect, it will give you warning about adding it to dependency array or not using it at all.
It sometimes causes the problem which might give you unpredictable output. So I suggest that you take a little effort to rewrite your function as class. There are very little changes, and you can have some components as class and some as function. You're not obligated to use only one convention.
Take this for example
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(...);
}
and
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(...);
}
This is only for example. so lets not talk about best practices or potential issues with the code. Both of this has same logic but the later only works as expected. You might get componentDidMount functionality with useEffect running for this time, but as your app grows, there are chances that you MAY face some issues. So, rather than rewriting at that phase, it's better to do this at early stage.
Besides, OOP is not that bad, if Procedure-Oriented Programming was enough, we would never have had Object-Oriented Programming. It's painful sometimes, but better (technically. personal issues aside).
There's no componentDidMount
on functional components, but React Hooks provide a way you can emulate the behavior by using the useEffect
hook.
Pass an empty array as the second argument to useEffect()
to run only the callback on mount only.
Please read the 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>
You want to use useEffect()
, which, depending on how you use the function, can act just like componentDidMount().
Eg. you could use a custom loaded
state property which is initially set to false, and switch it to true on render, and only fire the effect when this value changes.
the exact equivalent hook for componentDidMount() is
useEffect(()=>{},[]);
hope this helpful :)