componentDidMount
フックを介してReact機能コンポーネントでシミュレートする方法はありますか?
回答:
フックの安定バージョンの場合(Reactバージョン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
。これを読んでいる人は、2番目の引数を残すと、undefined
すべてのレンダリングでエフェクトがトリガーされることに注意してください(私が間違っていない場合)。
受け入れられた回答は機能しますが、お勧めしません。複数の状態があり、それをuseEffectで使用すると、依存関係配列に追加するか、まったく使用しないかについて警告が表示されます。
それは時々あなたに予測できない出力を与えるかもしれない問題を引き起こします。したがって、関数をクラスとして書き直すために少し努力することをお勧めします。変更はほとんどなく、一部のコンポーネントをクラスとして、一部を関数として使用できます。規則を1つだけ使用する義務はありません。
これを例に取ってください
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フックは、useEffect
フックを使用して動作をエミュレートする方法を提供します。
useEffect()
マウントでのみコールバックのみを実行するには、2番目の引数として空の配列を渡します。
のドキュメントを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
inreactフックに完全に相当するものはありません。
私の経験では、reactフックはそれを開発するときに異なる考え方を必要とし、一般的に言えば、のようなクラスメソッドと比較するべきではありませんcomponentDidMount
。
そうは言っても、フックを使用してと同様の効果を生み出す方法がいくつかありますcomponentDidMount
。
解決策1:解決策1:
useEffect(() => {
console.log("I have been mounted")
}, [])
解決策2:解決策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に切り替えて、この値が変更された場合にのみエフェクトを起動できます。