Можно ли совместно использовать состояния между компонентами, используя хук useState() в React?
Я экспериментировал с новой функцией Hook в React. Учитывая, что у меня есть следующие два компонента (с использованием React Hooks) -
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
не являются доступными. Например, изменение count
в HookComponent2
не приводит к изменению HookComponent
.
Можно ли делиться состояниями между компонентами с помощью useState()
hook?
Ответы
Ответ 1
Если вы ссылаетесь на состояние компонента, то хуки не помогут вам разделить его между компонентами. Состояние компонента является локальным для компонента. Если ваше состояние живет в контексте, то хук useContext
будет полезен.
По сути, я думаю, что вы неправильно поняли строку "разделение логики состояния между компонентами". Состояние логики отличается от состояния. Логика состояния - это то, что вы делаете, что изменяет состояние. Например, компонент подписывается на хранилище в componentDidMount()
и отменяет подписку в componentWillUnmount()
. Такое поведение подписки/отписки может быть реализовано в ловушке, и компоненты, которые нуждаются в этом поведении, могут просто использовать ловушку.
Если вы хотите поделиться состоянием между компонентами, есть несколько способов сделать это, каждый со своими достоинствами:
1. Поднимите состояние вверх
Поднимите состояние до общего предка двух компонентов.
function Ancestor() {
const [count, setCount] = useState(999);
return <>
<DescendantA count={count} />
<DescendantB count={count} />
</>;
}
Этот подход к совместному использованию состояний принципиально не отличается от традиционного способа использования состояния, хуки просто дают нам другой способ объявления состояния компонента.
2. Контекст
Если потомки находятся слишком глубоко в иерархии компонентов, и вы не хотите передавать состояние слишком многим слоям, вы можете использовать Context API.
Есть хук useContext
который вы можете использовать в дочерних компонентах.
3. Решение по управлению внешним государством
Государственные библиотеки управления, такие как Redux или Mobx. После этого ваш штат будет находиться в магазине за пределами React, и компоненты смогут подключаться/подписываться на магазин для получения обновлений.
Ответ 2
в документе говорится:
Мы импортируем UseState Hook из React. Это позволяет сохранить локальное состояние в функциональном компоненте.
он не упоминает, что состояние может быть разделено между компонентами, useState
hook просто дает вам более быстрый способ объявить поле состояния и его корреспондентский сеттер в одной команде.
Ответ 3
Вам все равно нужно поднять ваше состояние до компонента-предка HookComponent1 и HookComponent2. Это то, как вы делите состояние раньше, и последний хук api ничего не меняет.
Ответ 4
С крючками это не возможно напрямую. Я рекомендую вам взглянуть на реакцию легко-состояние. https://github.com/solkimicreb/react-easy-state
Я использую его в больших приложениях, и он работает как шарм.
Ответ 5
Я создал сумасшедший, который позволяет вам делать именно это - 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