Reactの新しいフック機能を試していました。次の2つのコンポーネントがあると考えます(Reactフックを使用)-
const HookComponent = () => {
const [username, setUsername] = useState('Abrar');
const [count, setState] = useState();
const handleChange = (e) => {
setUsername(e.target.value);
}
return (
<div>
<input name="userName" value={username} onChange={handleChange}/>
<p>{username}</p>
<p>From HookComponent: {count}</p>
</div>
)
}
const HookComponent2 = () => {
const [count, setCount] = useState(999);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
フックは、コンポーネント間でステートフルロジックを共有するという問題を解決すると主張していますが、HookComponent
とHookComponent2
の間の状態は共有できないことがわかりました。たとえば、HookComponent2
のcount
の変更は、HookComponent
の変更をレンダリングしません。
useState()
フックを使用してコンポーネント間で状態を共有することは可能ですか?
コンポーネントの状態を参照している場合、フックはコンポーネント間で共有するのに役立ちません。コンポーネントの状態は、コンポーネントに対してローカルです。状態がコンテキスト内にある場合、useContext
フックが役立ちます。
基本的に、「コンポーネント間でステートフルロジックを共有する」というラインを誤解していると思います。ステートフルロジックは状態とは異なります。ステートフルロジックとは、状態を変更するものです。たとえば、componentDidMount()
でストアにサブスクライブし、componentWillUnmount()
でサブスクライブ解除するコンポーネント。このサブスクライブ/サブスクライブ解除動作はフックに実装でき、この動作を必要とするコンポーネントはフックを使用するだけです。
コンポーネント間で状態を共有する場合、さまざまな方法があり、それぞれにメリットがあります。
2つのコンポーネントの共通の祖先コンポーネントまで状態を持ち上げます。
function Ancestor() {
const [count, setCount] = useState(999);
return <>
<DescendantA count={count} />
<DescendantB count={count} />
</>;
}
この状態共有のアプローチは、従来の状態の使用方法と根本的には異なりません。フックは、コンポーネントの状態を宣言するための異なる方法を提供するだけです。
子孫がコンポーネント階層の深すぎて、あまり多くのレイヤーに状態を渡したくない場合は、 Context API を使用できます。
子コンポーネント内で活用できるuseContext
フックがあります。
ReduxやMobxなどの状態管理ライブラリ。状態はReactの外部のストアに保存され、コンポーネントはストアに接続/サブスクライブして更新を受信できます。
doc 状態:
ReactからuseStateフックをインポートします。これにより、関数コンポーネントのローカル状態を保持できます。
状態をコンポーネント間で共有できることは言及していません。useState
フックは、1つの命令で状態フィールドとその対応するセッターを宣言するためのより迅速な方法を提供するだけです。
これを正確に実行できるhooksyを作成しました- https://github.com/pie6k/hooksy
import { createStore } from 'hooksy';
interface UserData {
username: string;
}
const defaultUser: UserData = { username: 'Foo' };
export const [useUserStore] = createStore(defaultUser); // we've created store with initial value.
// useUserStore has the same signature like react useState hook, but the state will be shared across all components using it
そして、後で任意のコンポーネントで
import React from 'react';
import { useUserStore } from './userStore';
export function UserInfo() {
const [user, setUser] = useUserStore(); // use it the same way like useState, but have state shared across any component using it (eg. if any of them will call setUser - all other components using it will get re-rendered with new state)
function login() {
setUser({ username: 'Foo' })
}
return (
<div>
{!user && <strong>You're logged out<button onPress={login}>Login</button></strong>}
{user && <strong>Logged as <strong>{user.username}</strong></strong>}
</div>
);
}
状態をHookComponent1およびHookComponent2の祖先コンポーネントに引き上げる必要があります。これが以前の状態の共有方法であり、最新のフックAPIはそれについて何も変更しません。
フックでは、直接は不可能です。反応しやすい状態を確認することをお勧めします。 https://github.com/solkimicreb/react-easy-state
私は大きなアプリでそれを使用し、それは魅力のように動作します。