Tıpkı aldığınız güzel uyarı gibi, React'te Anti-Pattern olan bir şey yapmaya çalışıyorsunuz. Bu bir hayır-hayır. React, bir ebeveynden çocuğa bir ilişkinin kesilmesi için tasarlanmıştır. Şimdi, bir çocuğun kendi başına bağlantısını kesmesini istiyorsanız, bunu çocuk tarafından tetiklenen ebeveynde bir durum değişikliği ile simüle edebilirsiniz. size kodla göstermeme izin verin.
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}
}
}
bu çok basit bir örnek. ancak ebeveyne bir eylemi aktarmanın kaba bir yolunu görebilirsiniz
Bununla birlikte, mağazanızın oluşturulmaya gittiğinde doğru verileri içermesine izin vermek için muhtemelen mağazadan (gönderim eylemi) geçmeniz gerektiği söyleniyor.
İki ayrı uygulama için hata / durum mesajları yaptım, ikisi de mağazadan geçti. Tercih edilen yöntem bu ... İsterseniz, bunun nasıl yapılacağına dair bazı kodlar gönderebilirim.
DÜZENLEME: İşte React / Redux / Typescript kullanarak bir bildirim sistemini nasıl kurduğum
İlk önce not edilecek birkaç şey. bu typcript içindedir, bu yüzden tür bildirimlerini kaldırmanız gerekir :)
İşlemler için lodash npm paketlerini ve satır içi sınıf adı ataması için sınıf adlarını (cx diğer adı) kullanıyorum.
Bu kurulumun güzelliği, eylem onu oluşturduğunda her bildirim için benzersiz bir tanımlayıcı kullanmamdır. (örneğin notify_id). Bu benzersiz kimlik birSymbol()
. Bu şekilde, herhangi bir zamanda herhangi bir bildirimi kaldırmak isterseniz, hangisini kaldıracağınızı bildiğiniz için yapabilirsiniz. Bu bildirim sistemi, istediğiniz kadar istiflemenize izin verecek ve animasyon tamamlandığında ortadan kalkacaktır. Animasyon olayına bağlanıyorum ve bittiğinde bildirimi kaldırmak için bazı kodları tetikliyorum. Ayrıca, animasyon geri aramasının tetiklenmemesi durumunda, bildirimi kaldırmak için bir geri dönüş zaman aşımı ayarladım.
bildirim 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);
};
};
bildirim 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
uygulamanız için temel oluşturmada bildirimleri
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>
);
}
kullanıcı notification.tsx
kullanıcı bildirim sınıfı
/*
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>
);
}
}