Abr*_*rar 20 javascript reactjs react-hooks
我正在试验React中的新Hook功能.考虑到我有以下两个组件(使用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>
);
}
Run Code Online (Sandbox Code Playgroud)
钩权利要求来解决的共享部件之间的有状态逻辑的问题,但我发现之间的状态HookComponent和HookComponent2不共享.例如,countin 的改变HookComponent2不会导致改变HookComponent.
是否可以使用useState()钩子在组件之间共享状态?
Yan*_*Tay 31
如果您指的是组件状态,那么钩子将无法帮助您在组件之间共享它.组件状态是组件的本地状态.如果你的国家生活在上下文中,那么useContext钩子会有所帮助.
从根本上说,我认为你误解了"在组件之间共享有状态逻辑"这一行.有状态逻辑与状态不同.有状态逻辑是你做的修改状态的东西.例如,订阅商店componentDidMount()和取消订阅的组件componentWillUnmount().这种订阅/取消订阅行为可以在钩子中实现,而需要这种行为的组件可以只使用钩子.
如果要在组件之间共享状态,有多种方法可以实现,每种方法都有自己的优点:
将状态提升到两个组件的共同祖先组件.
function Ancestor() {
const [count, setCount] = useState(999);
return <>
<DescendantA count={count} />
<DescendantB count={count} />
</>;
}
Run Code Online (Sandbox Code Playgroud)
这种状态共享方法与使用状态的传统方式没有根本的不同,钩子只是给我们一种不同的方式来声明组件状态.
如果后代在组件层次结构中太深,并且您不希望将状态向下传递太多层,则可以使用Context API.
useContext你可以在子组件中使用一个钩子.
像Redux或Mobx这样的状态管理库.然后,您的州将居住在React之外的商店中,组件可以连接/订阅商店以接收更新.
str*_*tss 21
没有任何外部状态管理库是可能的。只需使用一个简单的observable实现:
function makeObservable(target) {
let listeners = []; // initial listeners can be passed an an argument aswell
let value = target;
function get() {
return value;
}
function set(newValue) {
if (value === newValue) return;
value = newValue;
listeners.forEach((l) => l(value));
}
function subscribe(listenerFunc) {
listeners.push(listenerFunc);
return () => unsubscribe(listenerFunc); // will be used inside React.useEffect
}
function unsubscribe(listenerFunc) {
listeners = listeners.filter((l) => l !== listenerFunc);
}
return {
get,
set,
subscribe,
};
}
Run Code Online (Sandbox Code Playgroud)
然后创建一个 store 并使用subscribein钩住它以做出反应useEffect:
const userStore = makeObservable({ name: "user", count: 0 });
const useUser = () => {
const [user, setUser] = React.useState(userStore.get());
React.useEffect(() => {
return userStore.subscribe(setUser);
}, []);
const actions = React.useMemo(() => {
return {
setName: (name) => userStore.set({ ...user, name }),
incrementCount: () => userStore.set({ ...user, count: user.count + 1 }),
decrementCount: () => userStore.set({ ...user, count: user.count - 1 }),
}
}, [user])
return {
state: user,
actions
}
}
Run Code Online (Sandbox Code Playgroud)
这应该有效。不需要React.Context或提升状态
使用useBetween钩子可以做到这一点。
import React, { useState } from 'react';
import { useBetween } from 'use-between';
const useShareableState = () => {
const [username, setUsername] = useState('Abrar');
const [count, setCount] = useState(0);
return {
username,
setUsername,
count,
setCount
}
}
const HookComponent = () => {
const { username, setUsername, count } = useBetween(useShareableState);
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 } = useBetween(useShareableState);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
我们将 React hooks 有状态逻辑从HookComponent到useShareableState。我们在每个组件中调用useShareableStateusing useBetween。
useBetween是一种调用任何钩子的方法。但是这样状态就不会存储在 React 组件中。对于同一个钩子,调用的结果是一样的。所以我们可以在不同的组件中调用一个钩子并在一种状态上协同工作。当更新共享状态时,使用它的每个组件也将被更新。
| 归档时间: |
|
| 查看次数: |
9670 次 |
| 最近记录: |