Як і те приємне попередження, яке ви отримали, ви намагаєтесь зробити щось, що є анти-шаблоном в React. Це ні-ні. Реакт має на меті статися, що між батьком і дитиною трапляються незрозумілі стосунки. Тепер, якщо ви хочете, щоб дитина відключилася, ви можете імітувати це зі зміною стану батьків, яке викликається дитиною. дозвольте показати вам у коді.
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}
}
}
це дуже простий приклад. але ви можете бачити приблизний спосіб передати батькові дію
Зважаючи на те, що ви, ймовірно, повинні пройти через магазин (диспетчерська дія), щоб ваш магазин міг містити правильні дані, коли він відображатиметься
Я робив повідомлення про помилки / статус для двох окремих програм, обидва пройшли через магазин. Це кращий метод ... Якщо ви хочете, я можу опублікувати якийсь код, як це зробити.
EDIT: Ось, як я налаштував систему повідомлень за допомогою React / Redux / Typescript
Дещо слід зазначити спочатку. це в машинописі, тому вам потрібно буде видалити декларації типу :)
Я використовую lodash пакетів npm для операцій, а також імена класів (cx псевдонім) для вбудованого вбудованого імені класу.
Краса цієї установки полягає в тому, що я використовую унікальний ідентифікатор для кожного повідомлення, коли дія створює його. (наприклад, notify_id). Цей унікальний ідентифікатор - це Symbol()
. Таким чином, якщо ви хочете видалити будь-яке сповіщення в будь-який момент часу, ви можете, оскільки ви знаєте, яке саме видалити. Ця система сповіщень дозволить вам скласти стільки, скільки захочете, і вони відійдуть, коли анімація завершена. Я підключаюся до події анімації, і коли вона закінчується, я запускаю код, щоб видалити сповіщення. Я також встановив резервний час очікування, щоб видалити сповіщення на випадок, якщо зворотний виклик анімації не спрацює.
повідомлення-дії.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
у базовій візуалізації для вашої програми ви б надавали сповіщення
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>
);
}
користувач-сповіщення.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>
);
}
}