関数コンポーネントがあり、強制的に再レンダリングしたいと思います。
どうすればよいですか?
インスタンスthis
がないので、呼び出すことはできませんthis.forceUpdate()
。
関数コンポーネントがあり、強制的に再レンダリングしたいと思います。
どうすればよいですか?
インスタンスthis
がないので、呼び出すことはできませんthis.forceUpdate()
。
回答:
反応フックを使用useState()
して、関数コンポーネントを呼び出すことができるようになりました。
useState()
次の2つの配列を返します。
ます。1。現在の状態を表す値。
2.そのセッター。値を更新するために使用します。
そのセッターで値を更新すると、再描画にあなたの機能コンポーネントを強制的に、
同じようにforceUpdate
行います。
import React, { useState } from 'react';
//create your forceUpdate hook
function useForceUpdate(){
const [value, setValue] = useState(0); // integer state
return () => setValue(value => ++value); // update the state to force render
}
function MyComponent() {
// call your hook here
const forceUpdate = useForceUpdate();
return (
<div>
{/*Clicking on the button will force to re-render like force update does */}
<button onClick={forceUpdate}>
Click to re-render
</button>
</div>
);
}
上記のコンポーネントuseForceUpdate
は、ブール状態フック(useState
)を使用するカスタムフック関数()を使用します。ブール状態を切り替えて、レンダリング関数を再実行するようにReactに指示します。
この回答の古いバージョンでは、スニペットはブール値を使用し、でそれを切り替えましたforceUpdate()
。回答を編集したので、スニペットはブール値ではなく数値を使用します。
どうして ?(あなたは私に尋ねるでしょう)
あるときforceUpdate()
、2つの異なるイベントから2回呼び出されたため、ブール値が元の状態にリセットされ、コンポーネントがレンダリングされなかったためです。
であるためuseState
のセッター(setValue
ここでは)、React
新しいものと以前の状態を比較し、そして状態が異なる場合にのみレンダリングします。
forceUpdate
。
useState
フックについて話しているのでsetState
あって、実際には比較を行わないクラスではありません(shouldUpdateメソッドを実装しない限り)。私が投稿したのと同じデモを参照してください。ただし、に静的な値を使用するとsetState
、再度レンダリングされません。codesandbox.io
react v16.8を更新します(2019年2月16日リリース)
フックでリリースされたreact16.8以降、関数コンポーネントは永続的に保持できるようになりましたstate
。その能力であなたは今:を模倣することができますforceUpdate
:
このアプローチは再検討する必要があり、ほとんどの場合、更新を強制する必要がある場合は、おそらく何か間違ったことをしていることに注意してください。
反応する前に16.8.0
いいえ、できません。State-Less関数コンポーネントは正常でありfunctions
、を返します。jsx
から拡張していないため、ReactライフサイクルメソッドにアクセスできませんReact.Component
。
function-componentrender
は、クラスコンポーネントのメソッド部分と考えてください。
props
やstate
変更がない場合などです。ステートレスコンポーネントには関数がないため、レンダリング関数を強制することはできませんrender
。ステートレスコンポーネントはextends
React.Component
、を返す単なる関数ではありませんjsx
。
公式FAQ(https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate)では、本当に必要な場合にこの方法を推奨しています。
const [ignored, forceUpdate] = useReducer(x => x + 1, 0);
function handleClick() {
forceUpdate();
}
const [, forceUpdate] = useReducer(x => x + 1, 0);
use-force-updateというサードパーティのライブラリを使用して 、react機能コンポーネントを強制的にレンダリングしました。魅力のように働いた。プロジェクトにパッケージをインポートして、このように使用するだけです。
import useForceUpdate from 'use-force-update';
const MyButton = () => {
const forceUpdate = useForceUpdate();
const handleClick = () => {
alert('I will re-render now.');
forceUpdate();
};
return <button onClick={handleClick} />;
};
useForceUpdate
てuseCallback
いるように使用します。このライブラリは、いくつかのキーストロークを節約するための単なるユーティリティライブラリです。
免責事項:問題への回答ではありません。
ここに重要な注意を残します:
ステートレスコンポーネントを強制的に更新しようとしている場合は、デザインに問題がある可能性があります。
次の場合を考えてみましょう。
これは、コンポーネントに小道具を追加し、ステートレスコンポーネントの親コンポーネントに状態を追加する場合、フックを明示的に使用せずに実行できます。
const ParentComponent = props => {
const [updateNow, setUpdateNow] = useState(true)
const updateFunc = () => {
setUpdateNow(!updateNow)
}
const MyComponent = props => {
return (<div> .... </div>)
}
const MyButtonComponent = props => {
return (<div> <input type="button" onClick={props.updateFunc} />.... </div>)
}
return (
<div>
<MyComponent updateMe={updateNow} />
<MyButtonComponent updateFunc={updateFunc}/>
</div>
)
}
受け入れられた答えは良いです。理解しやすくするためだけに。
コンポーネントの例:
export default function MyComponent(props) {
const [updateView, setUpdateView] = useState(0);
return (
<>
<span style={{ display: "none" }}>{updateView}</span>
</>
);
}
再レンダリングを強制するには、以下のコードを呼び出します。
setUpdateView((updateView) => ++updateView);