Genau wie diese nette Warnung, die Sie erhalten haben, versuchen Sie, etwas zu tun, das ein Anti-Pattern in React ist. Dies ist ein Nein-Nein. React soll dazu führen, dass eine Beziehung zwischen Eltern und Kind aufgehoben wird. Wenn Sie nun möchten, dass sich ein Kind selbst abmeldet, können Sie dies mit einer Statusänderung im Elternteil simulieren, die vom Kind ausgelöst wird. Lass mich dir im Code zeigen.
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}
}
}
Dies ist ein sehr einfaches Beispiel. Sie können jedoch einen groben Weg erkennen, um eine Aktion an das übergeordnete Element weiterzuleiten
Davon abgesehen sollten Sie wahrscheinlich das Geschäft durchlaufen (Versandaktion), damit Ihr Geschäft beim Rendern die richtigen Daten enthält
Ich habe Fehler- / Statusmeldungen für zwei separate Anwendungen erstellt. Beide haben den Speicher durchlaufen. Es ist die bevorzugte Methode ... Wenn Sie möchten, kann ich einen Code dazu veröffentlichen.
BEARBEITEN: So richte ich ein Benachrichtigungssystem mit React / Redux / Typescript ein
Einige Dinge, die zuerst zu beachten sind. Dies ist in Typoskript, so dass Sie die Typdeklarationen entfernen müssten :)
Ich verwende die npm-Pakete lodash für Operationen und Klassennamen (cx-Alias) für die Zuweisung von Inline-Klassennamen.
Das Schöne an diesem Setup ist, dass ich für jede Benachrichtigung eine eindeutige Kennung verwende, wenn die Aktion sie erstellt. (zB notify_id). Diese eindeutige ID ist aSymbol()
. Auf diese Weise können Sie Benachrichtigungen zu jedem Zeitpunkt entfernen, da Sie wissen, welche Sie entfernen müssen. Mit diesem Benachrichtigungssystem können Sie so viele stapeln, wie Sie möchten, und diese verschwinden, wenn die Animation abgeschlossen ist. Ich bin mit dem Animationsereignis verbunden und wenn es beendet ist, löse ich einen Code aus, um die Benachrichtigung zu entfernen. Ich habe auch ein Fallback-Timeout eingerichtet, um die Benachrichtigung zu entfernen, falls der Animationsrückruf nicht ausgelöst wird.
Benachrichtigungsaktionen.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);
};
};
Benachrichtigungsreduzierer.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
Im Basis-Rendering für Ihre Anwendung würden Sie die Benachrichtigungen rendern
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>
);
}
user-notification.tsx
Benutzerbenachrichtigungsklasse
/*
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>
);
}
}