2016-04-01 3 views
1

У меня есть компонент сетки данных, где пользователь может выбрать несколько строк. Компонент управляет выбранные строки как часть своего состояния:Лучший способ уведомления компонента глобального события

var Datagrid = React.createClass({ 

    getInitialState() { 
    return { 
     selection: [] 
    } 
    }, 

    handleRowClick(id, event) { 
    if (event.ctrlKey) { 
     this.setState({ selection.concat([id]) }); 
    } 
    }, 

    render() { 
    return 
     <div> 
     {this.props.data.map(rowdata => <Row data={rowdata}>)} 
     </div> 
    ; 
    } 
}); 

ReactDOM.render(<Datagrid data={data}>, document.querySelector('#grid1')) 

Это работает и инкапсулирует (на самом деле довольно сложный) выбор логики хорошо.

Но теперь я хочу, чтобы этот компонент отменил выделение всех строк при нажатии на тело страницы.

Кажется довольно громоздким, чтобы глобальный магазин управлял выборами всех решеток данных, чтобы иметь возможность их отменить. Мне нравится тот факт, что логика выбора инкапсулирована в компонент, я просто хочу сообщить об этом глобальном событии.

у меня была идея прохождения обратного вызова в качестве реквизита, который сбрасывает себя, но это кажется очень запутанным:

var notification = false; 

body.onclick = function() { 

    notification = function() { notification = false; } // Marks a pending notification 

    ReactDOM.render(<Datagrid data={data} notification={notification}>, document.querySelector('#grid1')) 

} 

var Datagrid = React.createClass({ 
    ... 

    render() { 

    if (this.props.notification) { 
     this.setState({ selection: [] }); 
     this.props.notification(); // Reset the notification 
    } 

    ... 
    } 
}); 

ReactDOM.render(<Datagrid data={data} notification={notification}>, document.querySelector('#grid1')) 

Есть ли лучший способ?

ответ

0

Я считаю, что правильный способ справиться с этим делом настроен слушатель, когда компонент монтирует, а затем удалить его, когда он демонтирует так:

var Datagrid = React.createClass({ 

    getInitialState() { 
    return { 
     selection: [] 
    } 
    }, 

    componentDidMount() { 
    document.body.addEventListener('click', this.handleClear); 
    }, 

    componentWillUnmount() { 
    document.body.removeEventListener('click', this.handleClear); 
    }, 

    handleClear() { 
    this.setState({ selection: []}); 
    }, 

    handleRowClick(id, event) { 
    if (event.ctrlKey) { 
     this.setState({ selection.concat([id]) }); 
    } 
    }, 

    render() { 
    return 
     <div> 
     {this.props.data.map(rowdata => <Row data={rowdata}>)} 
     </div> 
    ; 
    } 
}); 
Смежные вопросы