sử dụng móc hoặc HOC chọn lựa của bạn
Sử dụng móc hoặc mẫu HOC (thành phần bậc cao hơn) , bạn có thể có các cập nhật tự động khi cửa hàng của bạn thay đổi. Đây là một cách tiếp cận rất nhẹ mà không có khung.
useStore Hook cách xử lý cập nhật cửa hàng
interface ISimpleStore {
on: (ev: string, fn: () => void) => void;
off: (ev: string, fn: () => void) => void;
}
export default function useStore<T extends ISimpleStore>(store: T) {
const [storeState, setStoreState] = useState({store});
useEffect(() => {
const onChange = () => {
setStoreState({store});
}
store.on('change', onChange);
return () => {
store.off('change', onChange);
}
}, []);
return storeState.store;
}
withStores HOC xử lý cập nhật cửa hàng
export default function (...stores: SimpleStore[]) {
return function (WrappedComponent: React.ComponentType<any>) {
return class WithStore extends PureComponent<{}, {lastUpdated: number}> {
constructor(props: React.ComponentProps<any>) {
super(props);
this.state = {
lastUpdated: Date.now(),
};
this.stores = stores;
}
private stores?: SimpleStore[];
private onChange = () => {
this.setState({lastUpdated: Date.now()});
};
componentDidMount = () => {
this.stores &&
this.stores.forEach((store) => {
// each store has a common change event to subscribe to
store.on('change', this.onChange);
});
};
componentWillUnmount = () => {
this.stores &&
this.stores.forEach((store) => {
store.off('change', this.onChange);
});
};
render() {
return (
<WrappedComponent
lastUpdated={this.state.lastUpdated}
{...this.props}
/>
);
}
};
};
}
Lớp học đơn giản
import AsyncStorage from '@react-native-community/async-storage';
import ee, {Emitter} from 'event-emitter';
interface SimpleStoreArgs {
key?: string;
defaultState?: {[key: string]: any};
}
export default class SimpleStore {
constructor({key, defaultState}: SimpleStoreArgs) {
if (key) {
this.key = key;
// hydrate here if you want w/ localState or AsyncStorage
}
if (defaultState) {
this._state = {...defaultState, loaded: false};
} else {
this._state = {loaded: true};
}
}
protected key: string = '';
protected _state: {[key: string]: any} = {};
protected eventEmitter: Emitter = ee({});
public setState(newState: {[key: string]: any}) {
this._state = {...this._state, ...newState};
this.eventEmitter.emit('change');
if (this.key) {
// store on client w/ localState or AsyncStorage
}
}
public get state() {
return this._state;
}
public on(ev: string, fn:() => void) {
this.eventEmitter.on(ev, fn);
}
public off(ev: string, fn:() => void) {
this.eventEmitter.off(ev, fn);
}
public get loaded(): boolean {
return !!this._state.loaded;
}
}
Cách sử dụng
Trong trường hợp móc:
// use inside function like so
const someState = useStore(myStore);
someState.myProp = 'something';
Trong trường hợp của HOC:
// inside your code get/set your store and stuff just updates
const val = myStore.myProp;
myOtherStore.myProp = 'something';
// return your wrapped component like so
export default withStores(myStore)(MyComponent);
ĐẢM BẢO
Để xuất các cửa hàng của bạn dưới dạng đơn lẻ để nhận được lợi ích của thay đổi toàn cầu như vậy:
class MyStore extends SimpleStore {
public get someProp() {
return this._state.someProp || '';
}
public set someProp(value: string) {
this.setState({...this._state, someProp: value});
}
}
// this is a singleton
const myStore = new MyStore();
export {myStore};
Cách tiếp cận này khá đơn giản và hiệu quả với tôi. Tôi cũng làm việc trong các nhóm lớn và sử dụng Redux và MobX và thấy những thứ đó cũng tốt nhưng chỉ là rất nhiều nồi hơi. Cá nhân tôi chỉ thích cách tiếp cận của riêng tôi bởi vì tôi luôn ghét rất nhiều mã cho một cái gì đó có thể đơn giản khi bạn cần nó.
this.forceUpdate()
là giải pháp phù hợp trong khi phần còn lại của tất cả các câu trả lời và một số ý kiến là không nên sử dụngforceUpdate()
. Điều đó có ổn không khi nói rằng câu hỏi chưa có giải pháp / câu trả lời phù hợp?