Sama seperti peringatan bagus yang Anda dapatkan, Anda mencoba melakukan sesuatu yang merupakan Anti-Pola di React. Ini adalah tidak-tidak. React dimaksudkan agar terjadi unmount dari hubungan orang tua ke anak. Sekarang jika Anda ingin seorang anak melepas dirinya sendiri, Anda dapat mensimulasikan ini dengan perubahan status pada induk yang dipicu oleh anak tersebut. biarkan saya menunjukkan kode.
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}
}
}
ini adalah contoh yang sangat sederhana. tetapi Anda dapat melihat cara kasar untuk menyampaikan kepada orang tua suatu tindakan
Karena itu, Anda mungkin harus melalui toko (tindakan pengiriman) untuk memungkinkan toko Anda berisi data yang benar ketika akan dirender
Saya telah melakukan pesan kesalahan / status untuk dua aplikasi terpisah, keduanya melalui toko. Ini adalah metode yang disukai ... Jika Anda mau, saya dapat memposting beberapa kode tentang cara melakukannya.
EDIT: Berikut adalah cara saya mengatur sistem notifikasi menggunakan React / Redux / Typecript
Beberapa hal yang perlu diperhatikan terlebih dahulu. ini ada di skrip ketikan jadi Anda harus menghapus deklarasi tipe :)
Saya menggunakan paket npm lodash untuk operasi, dan nama kelas (alias cx) untuk penetapan nama kelas inline.
Keindahan dari penyiapan ini adalah saya menggunakan pengenal unik untuk setiap notifikasi saat tindakan membuatnya. (mis. notify_id). ID unik ini adalah a Symbol()
. Dengan cara ini jika Anda ingin menghapus pemberitahuan apa pun kapan saja Anda bisa karena Anda tahu mana yang harus dihapus. Sistem notifikasi ini akan memungkinkan Anda menumpuk sebanyak yang Anda inginkan dan mereka akan hilang ketika animasi selesai. Saya mengaitkan ke acara animasi dan ketika selesai saya memicu beberapa kode untuk menghapus notifikasi. Saya juga menyiapkan batas waktu fallback untuk menghapus notifikasi kalau-kalau animasi callback tidak aktif.
notification-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);
};
};
notification-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
di render dasar untuk aplikasi Anda, Anda akan membuat notifikasi
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
kelas notifikasi pengguna
/*
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>
);
}
}