बस आपको मिली अच्छी चेतावनी की तरह, आप कुछ ऐसा करने की कोशिश कर रहे हैं जो प्रतिक्रिया में एक एंटी-पैटर्न है। यह एक नहीं-नहीं है। प्रतिक्रिया का उद्देश्य माता-पिता से बच्चे के रिश्ते में एक अनहोनी होना है। अब यदि आप चाहते हैं कि कोई बच्चा खुद को अनमाउंट करे, तो आप बच्चे द्वारा ट्रिगर किए गए माता-पिता में एक राज्य परिवर्तन के साथ इसे अनुकरण कर सकते हैं। मुझे कोड में दिखाते हैं।
class Child extends React.Component {
constructor(){}
dismiss() {
this.props.unmountMe();
}
render(){
// code
}
}
class Parent ...
constructor(){
super(props)
this.state = {renderChild: true};
this.handleChildUnmount = this.handleChildUnmount.bind(this);
}
handleChildUnmount(){
this.setState({renderChild: false});
}
render(){
// code
{this.state.renderChild ? <Child unmountMe={this.handleChildUnmount} /> : null}
}
}
यह एक बहुत ही सरल उदाहरण है। लेकिन आप माता-पिता को एक कार्रवाई से गुजरने के लिए एक मोटा रास्ता देख सकते हैं
कहा जा रहा है कि आपको स्टोर के माध्यम से जाना चाहिए (रेंडर एक्शन) जब आपके स्टोर को सही डेटा देने की अनुमति मिलती है जब वह रेंडर करने के लिए जाता है
मैंने दो अलग-अलग एप्लिकेशन के लिए त्रुटि / स्थिति संदेश किए हैं, दोनों स्टोर से गुजरे हैं। यह पसंदीदा तरीका है ... यदि आप चाहें तो मैं कुछ कोड पोस्ट कर सकता हूं कि यह कैसे करना है।
संपादित करें: यहां बताया गया है कि मैं कैसे प्रतिक्रिया / रिडक्स / टाइपस्क्रिप्ट का उपयोग करके एक अधिसूचना प्रणाली स्थापित करता हूं
पहले ध्यान देने योग्य बातें। यह टाइपस्क्रिप्ट में है इसलिए आपको प्रकार की घोषणाओं को हटाने की आवश्यकता होगी :)
मैं संचालन के लिए एनपीएम पैकेज लॉश का उपयोग कर रहा हूं, और इनलाइन क्लासनाम असाइनमेंट के लिए क्लासनाम (सीएक्स उर्फ)।
इस सेटअप की सुंदरता मैं प्रत्येक अधिसूचना के लिए एक अद्वितीय पहचानकर्ता का उपयोग करता हूं जब कार्रवाई इसे बनाता है। (उदा। Inform_id)। यह यूनिक आईडी एक है Symbol()
। इस तरह यदि आप किसी भी समय किसी भी अधिसूचना को हटाना चाहते हैं, क्योंकि आप जानते हैं कि किसको हटाना है। यह सूचना प्रणाली आपको जितने चाहें उतने स्टैक करने देगी और एनीमेशन पूरा होने पर वे चली जाएगी। मैं एनीमेशन ईवेंट में हुकिंग कर रहा हूं और जब यह खत्म होता है तो मैं नोटिफिकेशन निकालने के लिए कुछ कोड को ट्रिगर करता हूं। मैं भी एक कॉलबैक टाइमआउट सेट करता हूं, ताकि एनीमेशन कॉलबैक में आग न लगने पाए।
अधिसूचना-actions.ts
import { USER_SYSTEM_NOTIFICATION } from '../constants/action-types';
interface IDispatchType {
type: string;
payload?: any;
remove?: Symbol;
}
export const notifySuccess = (message: any, duration?: number) => {
return (dispatch: Function) => {
dispatch({ type: USER_SYSTEM_NOTIFICATION, payload: { isSuccess: true, message, notify_id: Symbol(), duration } } as IDispatchType);
};
};
export const notifyFailure = (message: any, duration?: number) => {
return (dispatch: Function) => {
dispatch({ type: USER_SYSTEM_NOTIFICATION, payload: { isSuccess: false, message, notify_id: Symbol(), duration } } as IDispatchType);
};
};
export const clearNotification = (notifyId: Symbol) => {
return (dispatch: Function) => {
dispatch({ type: USER_SYSTEM_NOTIFICATION, remove: notifyId } as IDispatchType);
};
};
अधिसूचना-reducer.ts
const defaultState = {
userNotifications: []
};
export default (state: ISystemNotificationReducer = defaultState, action: IDispatchType) => {
switch (action.type) {
case USER_SYSTEM_NOTIFICATION:
const list: ISystemNotification[] = _.clone(state.userNotifications) || [];
if (_.has(action, 'remove')) {
const key = parseInt(_.findKey(list, (n: ISystemNotification) => n.notify_id === action.remove));
if (key) {
// mutate list and remove the specified item
list.splice(key, 1);
}
} else {
list.push(action.payload);
}
return _.assign({}, state, { userNotifications: list });
}
return state;
};
app.tsx
आपके आवेदन के लिए आधार रेंडर में आप सूचनाएँ प्रस्तुत करेंगे
render() {
const { systemNotifications } = this.props;
return (
<div>
<AppHeader />
<div className="user-notify-wrap">
{ _.get(systemNotifications, 'userNotifications') && Boolean(_.get(systemNotifications, 'userNotifications.length'))
? _.reverse(_.map(_.get(systemNotifications, 'userNotifications', []), (n, i) => <UserNotification key={i} data={n} clearNotification={this.props.actions.clearNotification} />))
: null
}
</div>
<div className="content">
{this.props.children}
</div>
</div>
);
}
उपयोगकर्ता के notification.tsx
उपयोगकर्ता अधिसूचना वर्ग
/*
Simple notification class.
Usage:
<SomeComponent notifySuccess={this.props.notifySuccess} notifyFailure={this.props.notifyFailure} />
these two functions are actions and should be props when the component is connect()ed
call it with either a string or components. optional param of how long to display it (defaults to 5 seconds)
this.props.notifySuccess('it Works!!!', 2);
this.props.notifySuccess(<SomeComponentHere />, 15);
this.props.notifyFailure(<div>You dun goofed</div>);
*/
interface IUserNotifyProps {
data: any;
clearNotification(notifyID: symbol): any;
}
export default class UserNotify extends React.Component<IUserNotifyProps, {}> {
public notifyRef = null;
private timeout = null;
componentDidMount() {
const duration: number = _.get(this.props, 'data.duration', '');
this.notifyRef.style.animationDuration = duration ? `${duration}s` : '5s';
// fallback incase the animation event doesn't fire
const timeoutDuration = (duration * 1000) + 500;
this.timeout = setTimeout(() => {
this.notifyRef.classList.add('hidden');
this.props.clearNotification(_.get(this.props, 'data.notify_id') as symbol);
}, timeoutDuration);
TransitionEvents.addEndEventListener(
this.notifyRef,
this.onAmimationComplete
);
}
componentWillUnmount() {
clearTimeout(this.timeout);
TransitionEvents.removeEndEventListener(
this.notifyRef,
this.onAmimationComplete
);
}
onAmimationComplete = (e) => {
if (_.get(e, 'animationName') === 'fadeInAndOut') {
this.props.clearNotification(_.get(this.props, 'data.notify_id') as symbol);
}
}
handleCloseClick = (e) => {
e.preventDefault();
this.props.clearNotification(_.get(this.props, 'data.notify_id') as symbol);
}
assignNotifyRef = target => this.notifyRef = target;
render() {
const {data, clearNotification} = this.props;
return (
<div ref={this.assignNotifyRef} className={cx('user-notification fade-in-out', {success: data.isSuccess, failure: !data.isSuccess})}>
{!_.isString(data.message) ? data.message : <h3>{data.message}</h3>}
<div className="close-message" onClick={this.handleCloseClick}>+</div>
</div>
);
}
}